1
상호 TLS 연결을 구현하려고합니다. 여기 흐름입니다 : 클라이언트 인증서 및 secp512r1을 사용하는 TLS 1.2 연결이 실패합니다.
- 내가 CSR 요청을 생성 (타원 곡선 키를 사용하여이 secp512r1)
- 은 서버에 서명 요청을 보내고 나는 P12 인증서하게
- 응답으로 공개 키 인증서를받을 2 단계에서받은 공개 키 인증서를 내 ECC secp512r1 개인 키로 사용합니다. 나는 문서에서 "ca.p12"파일로 저장
- 나는
NSURLAuthenticationMethodClientCertificate
도전은 내가 SSL 오류가 발생하여 서버에 보안 연결을 할 수 없습니다 "Error Domain=NSURLErrorDomain Code=-1200
을 가져 인증서 - 에서 자격 증명을 사용하여 해결 얻을 때 . "
서버와 클라이언트 간의 트래픽을 확인하는 동안 클라이언트 쪽 문제인 것처럼 보입니다.
질문 :
- 합니까 아이폰 OS 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
}
에 전달. 또한, 서버는'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 -explained-plus-anofficial-patch /), [SSL_OP_SAFARI_ECDHE_ECDSA_BUG] (https://wiki.openssl.org/index.php/SSL_OP_SAFARI_ECDHE_ECDSA_BUG) 등)에 대한 정보를 제공합니다. 문제가 무엇인지 알아 내기 위해 클라이언트 인증서를 secp512r1 커브에서 분리해야한다고 생각합니다. secp256k1을 사용하면 클라이언트 인증서를 테스트했을 것입니다. openssl s_client 또는 다른 도구로 클라이언트 인증서를 테스트 할 수 있습니까? – jww