簡體   English   中英

獲取Apple Keychain以識別Bouncy Castle .NET創建的PKCS12(.p12)商店

[英]Get Apple Keychain to recognize Bouncy Castle .NET created PKCS12 (.p12) store

我們的組織為多個客戶管理穩定的iOS應用程序,這意味着處理許多不同的開發者身份證書和推送通知證書。

我在Bouncy Castle C#Crypto API上取得了成功,簡化了推送通知的證書和私鑰的管理, 基本上不再需要我們所有推送通知證書的鑰匙串

我想將此擴展到開發人員身份證書。 目標是將每個開發者身份的所有私鑰和證書信息存儲在數據庫中。 然后,當需要配置新的開發人員或構建計算機時,服務器端代碼可以將所有證書和私鑰包裝到一個p12存檔中,其中一個密碼可以導入到目標Mac的Keychain中。

不幸的是,Mac Keychain不喜歡我正在生成的p12文件。 這很煩人,因為我可以成功地將這些文件導入Windows證書管理器。

我正在使用的代碼(重要部分)如下所示:

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;
    }
}

就像我說的,這適用於在Windows上導入,但在導入Mac Keychain時失敗並出現非常一般的錯誤。

加載Keychain生成的p12和我自己生成的p12文件時,我可以看到一個主要的區別,但我不知道這是否是原因。

如果我將Mac Keychain生成的p12加載到Bouncy Castle PKCS12Store中,然后檢查密鑰,在Keychain p12上,證書和私鑰都有一個屬性,其密鑰為“1.2.840.113549.1.9.21”,具有等效值(值為#af8a1d6891efeb32756c12b7bdd96b5ec673e11e的DerOctetString)。

如果我對生成的p12文件執行相同操作,則私鑰包含“1.2.840.113549.1.9.21”屬性,但證書不包含。

如果我谷歌“1.2.840.113549.1.9.21” ,我發現這個OID意味着PKCS_12_LOCAL_KEY_ID 我唯一的理論是Keychain依賴於此來匹配證書和私鑰,而我生成的文件沒有這個,所以它失敗了。

但是,我嘗試將這些值添加到Hashtable,然后使用帶有屬性哈希表的CertificateEntry構造函數。 如果我這樣做,然后保存字節,然后重新加載字節,該屬性再次丟失。

所以我很沮喪。 也許這個屬性是Bouncy Castle API的一個小故障? 也許有些事我做錯了。 也許Keychain對傳入的p12文件有非常荒謬的非標准要求。 無論如何,我們將非常感謝您提供的任何幫助。

BouncyCastle的Pkcs12Store負責為您設置Friendly Name和Local Key ID屬性(或者至少在1.7版本中,大約在2011年4月)。 我的猜測是你必須使用舊版本才能使用。

以下是我將iPhone Developer身份保存到Pkcs12Store實例的方法(省略額外的東西和安全性):

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());

在OS X 10.7上的Keychain Access.app中導入存儲正確地將證書和私鑰放在鑰匙串中,並將證書放在UI中的私鑰內,就像Keychain Access本身生成的證書和密鑰一樣。

另外,似乎Pkcs12Store使用證書的公鑰來生成證書和密鑰條目共享的LocalKeyId屬性的值。

您可以在此處查看 Pkcs12Store源的相關部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM