2017-12-05 21 views
1

온라인으로이 문제를 해결하기 위해 온라인에서 읽은 시간이 지나면 여기에 내 질문을 게시하기로 결정했습니다. 내 목표는 간단합니다. iOS 용 Xamarin을 사용하여 KeyChain에 X509Certficate를 저장하십시오. 이것은 BouncyCastle 라이브러리를 사용하여 생성 한 자체 서명 인증서입니다. 성공 적으로 가져 왔지만 SecKeyChain.Add을 사용하여 KeyChain에 저장할 때 결과는 항상 SecStatusCode.Param이며 설명서에 설명되어 있지 않거나 잘못된 매개 변수가 있습니다. 사용 방법은 다음과 같습니다.Xamarin에서 SecKeyChain을 사용하여 KeyChain에 인증서를 저장할 수 없습니다.

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 문서화 사이트에 주어진 예제들을 성공하지 못했다. 고맙습니다.

+0

'Entitlements.plist'에서 키 체인을 활성화 했습니까? –

+0

내가 그랬어, 그건 문제가 아니야. 문제를 해결 한 코드와 함께 답변을 추가했습니다. –

답변

1

다른 누구도 동일한 문제가 발생하는 경우 여기에서 내 해결책에 답하십시오. 문제는 SecRecord에 제공된 인증서가 SecCertificate이 아니므로 SecImportExport.ImportPkcs12을 사용하는 것이 잘못된 방법이었습니다. 대신 SecIdentity.Import을 사용하여 결국 인증서의 개인 키뿐만 아니라 인증서에 대한 참조를 제공합니다. 인증서와 개인 키는 ID를 사용하여 키 체인에 별도로 추가해야합니다. 이 코드는 다음과 같습니다.

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에서 매개 변수로 인증서를 사용하여 조회해야합니다. 이 시점부터 ID 인스턴스에서 개인 키의 서명 및 암호 해독에 액세스 할 수 있습니다.