1
私は相互TLS接続を実装しようとしています。ここで流れは次のとおりです。クライアント証明書とsecp512r1を使用したTLS 1.2接続が失敗します
- 私は(楕円曲線キーを使用して、secp512r1)CSR要求を生成
- 私はP12証明書を作成し、サーバーへの署名要求を送信し、応答
- として、公開鍵証明書を受け取ります手順2で受信した公開鍵証明書をECC secp512r1秘密鍵で使用します。私は
Error Domain=NSURLErrorDomain Code=-1200
は、「SSLエラーが発生した取得とサーバーへの安全な接続を行うことができない私はNSURLAuthenticationMethodClientCertificate
挑戦を得るとき、私は - この証明書の資格情報を使用して、それを解決
- 文書で「ca.p12」ファイルとして保存します"
サーバーとクライアントの間のトラフィックを確認している間に、クライアント側の問題と思われます。
質問:
- は、iOS 9/10サポート楕円曲線キー、TLSハンドシェイクでsecp512r1していますか?
- 迷ったことはありますか?
ご意見、ご提案は本当に感謝しています。ありがとう。
public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {
//server trust works fine
if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
if (self.shouldTrustProtectionSpace(space: challenge.protectionSpace)) {
completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
}
}
//This one causes the issue
else if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate) {
let identityAndTrust: IdentityAndTrust = self.extractIdentity()
let urlCredential: URLCredential = URLCredential(
identity: identityAndTrust.identityRef,
certificates: identityAndTrust.certArray as? [AnyObject],
persistence: URLCredential.Persistence.forSession)
completionHandler(.useCredential, urlCredential)
}
}
struct IdentityAndTrust {
var identityRef: SecIdentity
var trust: SecTrust
var certArray: AnyObject
}
func extractIdentity() -> IdentityAndTrust {
var identityAndTrust: IdentityAndTrust!
var securityError: OSStatus = errSecSuccess
var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
path = path + "/ca.p12"
//let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")!
let PKCS12Data = NSData(contentsOfFile:path)!
let key: NSString = kSecImportExportPassphrase as NSString
let options: NSDictionary = [key : "123"]
//create variable for holding security information
//var privateKeyRef: SecKeyRef? = nil
var items: CFArray?
securityError = SecPKCS12Import(PKCS12Data, options, &items)
if securityError == errSecSuccess {
let certItems: CFArray = items as CFArray!
let certItemsArray: Array = certItems as Array
let dict: AnyObject? = certItemsArray.first
if let certEntry: Dictionary = dict as? Dictionary<String, AnyObject> {
// grab the identity
let identityPointer: AnyObject? = certEntry["identity"]
let secIdentityRef: SecIdentity = identityPointer as! SecIdentity!
print("\(identityPointer) :::: \(secIdentityRef)")
// grab the trust
let trustPointer: AnyObject? = certEntry["trust"]
let trustRef: SecTrust = trustPointer as! SecTrust
print("\(trustPointer) :::: \(trustRef)")
// grab the certificate chain
var certRef: SecCertificate?
SecIdentityCopyCertificate(secIdentityRef, &certRef)
let certArray: NSMutableArray = NSMutableArray()
let reader = DmailReader.sharedReader
let caCertString = reader.getCACert()
let cerData = X509Utility.der(fromData: caCertString)
let convertedData = cerData as! CFData
let caCert = SecCertificateCreateWithData(nil, convertedData)
certArray.add(certRef as SecCertificate!)
certArray.add(caCert!)
identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray: certArray)
}
}
return identityAndTrust
}
でそれを渡して、チェーン内のすべての証明書は、(必須?) 'secp512r1'を使用する必要があります。さらに、サーバは 'secp512r1'をサポートしなければなりません。 'secp512r1'が問題であるかどうかを調べるには、' secp256k1'でテストしてください。最も一般的な曲線であり、この分野で最も相互運用性があります。 – jww
@jwwサーバーはsecp512rしかサポートしていないので、残念ながら私はsecp256でテストできません –
問題は、AppleのSecureTransportがバグかもしれないということです。 Appleは、ソフトウェアの品質が悪いことでよく知られています(cf. [goto fail](https://nakedsecurity.sophos.com/2014/02/24/anatomy-of-a-goto-fail-apples-ssl-bug非公式パッチ+)、[SSL_OP_SAFARI_ECDHE_ECDSA_BUG](https://wiki.openssl.org/index.php/SSL_OP_SAFARI_ECDHE_ECDSA_BUG)など)が含まれています。クライアント証明書をsecp512r1カーブから分離して、どちらが問題かを発見する必要があると思います。 secp256k1を使用すると、クライアント証明書がテストされます。 'openssl s_client'や他のツールを使ってクライアント証明書をテストできますか? – jww