Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7700387
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T22:41:48+00:00 2026-05-31T22:41:48+00:00

Our organization manages a stable of iOS applications for multiple clients, which means dealing

  • 0

Our organization manages a stable of iOS applications for multiple clients, which means dealing with a lot of different developer identity certificates and push notification certificates.

I have had success with the Bouncy Castle C# Crypto API in simplifying management of the certificates and private keys for push notifications, essentially eliminating the need for the Keychain for all our push notification certificates.

I would like to extend this to the developer identity certificates. The goal would be to store all the private key and certificate information in the database for each developer identity. Then when a new developer or build machine needs to be provisioned, server side code could wrap all of the certificates and private keys into one p12 archive with one password that could be imported into the target Mac’s Keychain.

Unfortunately, the Mac Keychain doesn’t like the p12 files I’m generating. This is annoying since I can successfully import these files into the Windows certificate manager just fine.

The code I’m using (the important parts) looks like this:

private byte[] GetP12Bytes(List<DevIdentity> identities, string password)
{
    Pkcs12Store store = new Pkcs12Store();

    foreach(DevIdentity ident in identities)
    {
        // Easiest to create a Bouncy Castle cert by converting from .NET
        var dotNetCert = new X509Certificate2(ident.CertificateBytes);
        // This method (not shown) parses the CN= attribute out of the cert's distinguished name
        string friendlyName = GetFriendlyName(dotNetCert.Subject); 

        // Now reconstitute the private key from saved value strings
        BigInteger modulus = new BigInteger(ident.PrivateKey.Modulus);
        BigInteger publicExponent = new BigInteger(ident.PrivateKey.PublicExponent);
        BigInteger privateExponent = new BigInteger(ident.PrivateKey.Exponent);
        BigInteger p = new BigInteger(ident.PrivateKey.P);
        BigInteger q = new BigInteger(ident.PrivateKey.Q);
        BigInteger dP = new BigInteger(ident.PrivateKey.DP);
        BigInteger dQ = new BigInteger(ident.PrivateKey.DQ);
        BigInteger qInv = new BigInteger(ident.PrivateKey.QInv);
        RsaKeyParameters kp = new RsaPrivateCrtKeyParameters(modulus, publicExponent, privateExponent, p, q, dP, dQ, qInv);
        AsymmetricKeyEntry privateKey = new AsymmetricKeyEntry(kp);

        // Now let's convert to a Bouncy Castle cert and wrap it for packaging
        Org.BouncyCastle.X509.X509Certificate cert = DotNetUtilities.FromX509Certificate(dotNetCert);
        X509CertificateEntry certEntry = new X509CertificateEntry(cert);

        // Set the private key and certificate into the store
        store.SetCertificateEntry(friendlyName, certEntry);
        store.SetKeyEntry(ident.PrivateKeyName, privateKey, new X509CertificateEntry[] { certEntry });
    }

    using (MemoryStream ms = new MemoryStream())
    {
        store.Save(ms, password.ToCharArray(), new SecureRandom());
        ms.Flush();
        byte[] p12Bytes = ms.ToArray();
        return p12Bytes;
    }
}

Like I said, this works great for import on Windows, but fails with a very generic error when importing into the Mac Keychain.

There is one major difference I can see when loading a Keychain-generated p12 and my own generated p12 file, but I do not know if this is the cause.

If I load the Mac Keychain generated p12 into a Bouncy Castle PKCS12Store, and then examine the keys, on the Keychain p12, both the certificate and the private key have an attribute with the key “1.2.840.113549.1.9.21” with equivalent values (a DerOctetString with value #af8a1d6891efeb32756c12b7bdd96b5ec673e11e).

If I do the same to my generated p12 file, the private key contains the “1.2.840.113549.1.9.21” attribute, but the Certificate does not.

If I Google “1.2.840.113549.1.9.21”, I find out that this OID means PKCS_12_LOCAL_KEY_ID . My only theory is that the Keychain relies on this to match up the certificate and private key, and that my generated file does not have this, so it fails.

However, I’ve tried adding these values to a Hashtable and then using the CertificateEntry constructor that takes the attribute hashtable. If I do that, and then save the bytes, and then reload the bytes, that attribute is again missing.

So I’m flummoxed. Maybe this attribute is a glitch in the Bouncy Castle API? Maybe there’s something I’m doing wrong. Maybe the Keychain has ridiculous non-standard requirements for incoming p12 files. In any case, any help that could be provided would be greatly appreciated.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T22:41:49+00:00Added an answer on May 31, 2026 at 10:41 pm

    BouncyCastle’s Pkcs12Store takes care of setting both the Friendly Name and Local Key ID attributes for you (or at least it does so in the 1.7 release, circa April 2011). My guess is that you must have used an older version where this didn’t work.

    Here’s how I’m saving an iPhone Developer identity to a Pkcs12Store instance (extra stuff and security omitted):

    var store = new Pkcs12Store();
    
    // pairs is IEnumerable<Tuple<X509Certificate, AsymmetricKeyParameter>>
    foreach (var pair in pairs)
    {
        var cn = pair.Item1.SubjectDN
             .GetValueList(X509Name.CN).OfType<string>().Single();
    
        var certEntry = new X509CertificateEntry(pair.Item1);
        store.SetCertificateEntry(cn, certEntry);
    
        var keyEntry = new AsymmetricKeyEntry(pair.Item2);
        store.SetKeyEntry("Developer Name", keyEntry, new[] { certEntry });
    }
    
    store.Save(stream, string.Empty.ToArray(), new SecureRandom());
    

    Importing the store in Keychain Access.app on OS X 10.7 correctly places the certificate and private key in the keychain and places the certificate within the private key in the UI, as with a certificate and key generated by Keychain Access itself.

    On a side note, it seems that Pkcs12Store uses the public key of the certificate to generate the value of the LocalKeyId attribute shared by the certificate and key entries.

    You can see the relevant section of the Pkcs12Store source here.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

problem is existing applications on our organization required to enter same data multiple times,
In our organization, members who achieve certain goals can earn different awards. Management wants
In our organization we have some projects which are (by policy) open to all
I am developing eclipse plugin for our organization . We are opening multiple servers[minimum
We have a use case in our organization, for which using redis as in-memory
We recently had a developer leave our organization. We're not sure if the version
Our organization has a very large database which Replicates to separate global servers. In
Our organization provides a variety of services to our clients (e.g., web hosting, tech
Our organization's software is compiled for the .NET 3.5 Framework. We have some customers
Our organization is moving towards a new case management system. One of the functions

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.