1
我試圖實現相互TLS連接。這裏是流量:使用客戶端證書和secp512r1失敗的TLS 1.2連接
- 我生成CSR請求(使用橢圓曲線密鑰,secp512r1)
- 發送簽名請求到服務器並接收的公鑰證書作爲響應
- 我讓P12證書使用步驟2中收到的公鑰證書和我的ECC secp512r1私鑰。我把它保存爲文檔「ca.p12」文件
- ,當我得到
NSURLAuthenticationMethodClientCertificate
挑戰我使用的憑據從此證書 - 獲取
Error Domain=NSURLErrorDomain Code=-1200
「發生SSL錯誤,無法進行到服務器的安全連接解決它「。
雖然檢查服務器和客戶端之間的流量似乎是客戶端問題。
問題:
- 確實iOS的9/10支持橢圓曲線按鍵,secp512r1在TLS握手?
- 我錯過了什麼?
任何想法,建議真的很感激。謝謝。
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
}
根據PKIX(網絡的PKI),在鏈應該(必須?)的所有證書使用'secp512r1'。另外,服務器必須支持'secp512r1'。要查看'secp512r1'是否是問題,請使用'secp256k1'測試。它是最常見的曲線,並提供了該領域最多的互操作性。 – jww
@jww不幸的是,我不能使用secp256進行測試,因爲服務器只支持secp512r –
嗯,問題是Apple的SecureTransport可能是越野車。蘋果以其軟件質量差而聞名(參見[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