嗨,大家好我正在尝试应用此身份验证strategy。基本上我创建RSA密钥对,然后我创建CSR(证书签名请求),然后我发送到服务器,它将返回(X.509)自签名客户端证书作为响应。然后我删除---- BEGIN CERTIFICATE ----和---- END CERTIFICATE ----,将其转换为行长为64个字符的base64编码数据,并以这种方式将其保存到keychain
let certRef: CFTypeRef? = SecCertificateCreateWithData(nil , cert)
let params: NSDictionary = [kSecClass as String: kSecClassCertificate, kSecValueRef as String: certRef!]
let status = SecItemAdd(params, nil)
证书已保存,现在如果我理解正确,如果我在密钥链中保存了创建CSR的私钥,我应该能够获得我将在NSURLSession中使用的SecIdentity
来发出请求。所以我创建了获取此身份的方法,这就是它的样子:
func getIdentityReference() -> SecIdentityRef? {
let parameters = [
kSecClass as String: kSecClassIdentity,
kSecAttrApplicationTag as String: kAsymmetricCryptoManagerApplicationTag,
kSecReturnRef as String: true
]
var ref: AnyObject?
let status = SecItemCopyMatching(parameters, &ref)
if status == errSecSuccess { return ref as! SecIdentityRef? } else { return nil }
}
一切正常,我得到身份所以唯一要做的就是实际请求。为此,我需要实现NSURLSessionDelegate&s确实接受了挑战方法,这里是
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
let method = challenge.protectionSpace.authenticationMethod
print(method)
if method == NSURLAuthenticationMethodServerTrust {
let host = challenge.protectionSpace.host
print(host)
let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, credential)
}
let identity = AsymmetricCryptoManager.sharedInstance.getIdentityReference()!
var certificate: SecCertificateRef? = nil
SecIdentityCopyCertificate(identity, &certificate)
var certArray = [certificate!]
let credential = NSURLCredential(identity: identity, certificates: certArray, persistence: .Permanent)
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, credential)
}
(我只是原型设计,这是隐式解包的原因)
但是当我发出此请求时,我收到了错误
Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9824, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x13cfe7850 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9824, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9824}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://blabla.blabla, NSErrorFailingURLStringKey=https://blabla.blabla, _kCFStreamErrorDomainKey=3}
现在我真的不知道问题出在哪里,请注意在Android上一切正常,所以服务器设置正确。任何帮助将不胜感激,它可能会帮助将来很少的人。 谢谢