簡體   English   中英

無法在Xamarin中使用SecKeyChain將證書存儲到KeyChain

[英]Cannot store Certificate to KeyChain using SecKeyChain in Xamarin

在花了幾個小時閱讀在線解決問題的方法之后,我決定在這里發表我的問題。 我的目標很簡單:使用Xamarin for iOS將X509Certficate存儲到KeyChain。 這是我使用BouncyCastle庫生成的自簽名證書。 我已經成功導入了它,但是當使用SecKeyChain.Add保存到KeyChain時,結果始終是SecStatusCode.Param ,該文檔說明缺少或參數無效。 這是我使用的方法

public static bool StoreCertInKeyChain(X509Certificate2 certificate, string password)
{
    var data = certificate.Export(X509ContentType.Pkcs12, password);

    var options = NSMutableDictionary.FromObjectAndKey(FromObject(password), SecImportExport.Passphrase);

    var statusCode = SecImportExport.ImportPkcs12(data, options, out NSDictionary[] result);
    if (statusCode != SecStatusCode.Success) return false;

    var certChain = result[0][SecImportExport.CertChain];
    var record = new SecRecord(SecKind.Certificate)
    {
        Label = "MyKey",
        Account = "Certificate",
        ApplicationTag = "MyTag"
    };
    record.SetValueRef(certChain);

    // Using the below code instead, produces the same result
    // var cert = new SecCertificate(certChain.Handle);
    // record.SetValueRef(cert);

    var resultAdd = SecKeyChain.Add(record);
    return resultAdd == SecStatusCode.Success;
}

有人遇到過這個問題嗎? 我沒有其他嘗試方法。 我沒有遵循Xamarin文檔站點上給出的示例。 謝謝

在這里回答我的解決方案,以防其他人遇到相同的問題。 問題是,在提供的證書SecRecord不是實例SecCertificate ,所以使用SecImportExport.ImportPkcs12是錯誤的方式做到這一點。 我最終改用了SecIdentity.Import ,它提供了對證書以及其中的私鑰的引用。 證書和私鑰需要使用身份分別添加到密鑰鏈中。 這是完成此操作的代碼。

    var identity = SecIdentity.Import(certificate.Export(X509ContentType.Pkcs12, password), password);
    var storedCertificate = SecKeyChain.QueryAsConcreteType(new SecRecord(SecKind.Certificate) { Label = "My Cert" }, out SecStatusCode statusCode);
    if (statusCode != SecStatusCode.Success)
    {
        var record = new SecRecord(SecKind.Certificate);
        record.Label = "My Cert";
        record.SetValueRef(identity.Certificate);
        var result = SecKeyChain.Add(record);

        SecKeyChain.AddIdentity(identity);

        storedCertificate = SecKeyChain.QueryAsConcreteType(new SecRecord(SecKind.Certificate) { Label = "My Cert" }, out statusCode);
    }
    var storedIdentity = SecKeyChain.FindIdentity(storedCertificate as SecCertificate);

可以使用標簽來檢索證書,但是要獲取私鑰,必須使用證書作為SecKeyChain.FindIdentity參數來查詢身份。 從這一點開始,可以從身份實例訪問對私鑰進行簽名和解密。

暫無
暫無

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

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