在 swift 中使用 public 密钥加密

using public key encryption in swift

我正在尝试使用网络服务开发人员提供给我的 public 密钥来安全地传输数据。我已经很努力了,但我找不到任何最新 swift 版本的工作示例。我将其编码如下(在 here:

的帮助下
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){
    if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
        var localTrust: UnsafeMutablePointer<SecTrust?>
        let serverTrust = challenge.protectionSpace.serverTrust!
        let serverPublicKey = SecTrustCopyPublicKey(serverTrust)
        let certificateData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("pinning-certificate", ofType: "der")!)
        let localCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, certificateData!)
        let policy = SecPolicyCreateBasicX509()

        if SecTrustCreateWithCertificates(localCertificate!, policy, localTrust) == errSecSuccess {
            let localTrustRef = localTrust
            let localPublicKey = SecTrustCopyPublicKey(localTrustRef)!
            if (localPublicKey as AnyObject).isEqual(serverPublicKey as! AnyObject) {
                print("trusted")
                return challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
            }
        }
    }
    print("not trusted")
    return challenge.sender!.cancelAuthenticationChallenge(challenge)
   }

但我在 SecTrustCreateWithCertificates() 和 SecTrustCopyPublicKey() 编译期间遇到以下错误: 无法将类型 'UnsafeMutablePointer?' 的值转换为预期的参数类型 'UnsafeMutablePointer'(又名 'UnsafeMutablePointer>')

编辑 1: 我已将我的代码更改为以下内容,现在我的代码已执行但服务器未收到任何请求:

func extractIdentity(certData:NSData) -> IdentityAndTrust {
    var identityAndTrust:IdentityAndTrust!
    var securityError:OSStatus = errSecSuccess

    let path: String = NSBundle.mainBundle().pathForResource("MobileAppClient", ofType: "pfx")!
    let PKCS12Data = NSData(contentsOfFile:path)!
    let key : NSString = kSecImportExportPassphrase as NSString
    let options : NSDictionary = [key : "client"]

    //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:SecIdentityRef = identityPointer as! SecIdentityRef!;
            print("\(identityPointer)  :::: \(secIdentityRef)")
            // grab the trust
            let trustPointer:AnyObject? = certEntry["trust"];
            let trustRef:SecTrustRef = trustPointer as! SecTrustRef;
            print("\(trustPointer)  :::: \(trustRef)")
            // grab the cert
            let chainPointer:AnyObject? = certEntry["chain"];
            identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray:  chainPointer! as! NSArray);
        }
    }
    return identityAndTrust;
}
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){

    if challenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) {

        let serverTrust:SecTrustRef = challenge.protectionSpace.serverTrust!
        let certificate: SecCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)!
        let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
        let cerPath: String = NSBundle.mainBundle().pathForResource("Certificates", ofType: "cer")!
        let localCertificateData = NSData(contentsOfFile:cerPath)!

        challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)

                    if (remoteCertificateData.isEqualToData(localCertificateData) == true) {
            let credential:NSURLCredential = NSURLCredential(forTrust: serverTrust)

            challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)

        } else {
            SVProgressHUD.dismiss()
            return challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
        }

    }
    else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate
    {

        let path: String = NSBundle.mainBundle().pathForResource("Certificates", ofType: "p12")!
        let PKCS12Data = NSData(contentsOfFile:path)!


        let identityAndTrust:IdentityAndTrust = self.extractIdentity(PKCS12Data);



        let urlCredential:NSURLCredential = NSURLCredential(
            identity: identityAndTrust.identityRef,
            certificates: identityAndTrust.certArray as? [AnyObject],
            persistence: NSURLCredentialPersistence.ForSession);
        challenge.sender?.useCredential(urlCredential, forAuthenticationChallenge: challenge)


    }

}

我认为有两个问题:

1) 要投射 UnsafeMutablePointer 你应该调用 localTrust.memory 但它会给你下一个错误 2)下一个错误会给你未初始化的指针,我想你可以使用这样的代码:

func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){
    if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
        var localTrust: UnsafeMutablePointer<SecTrust?> = nil
        let serverTrust = challenge.protectionSpace.serverTrust!
        let serverPublicKey = SecTrustCopyPublicKey(serverTrust)
        let certificateData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("pinning-certificate", ofType: "der")!)
        let localCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, certificateData!)
        let policy = SecPolicyCreateBasicX509()

        if SecTrustCreateWithCertificates(localCertificate!, policy, localTrust) == errSecSuccess {
            let localTrustRef = localTrust
            let localPublicKey = SecTrustCopyPublicKey(localTrustRef.memory!)!
            if (localPublicKey as AnyObject).isEqual(serverPublicKey as! AnyObject) {
                print("trusted")
                return challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
            }
        }
    }
    print("not trusted")
    return challenge.sender!.cancelAuthenticationChallenge(challenge)
}

P.s。强制施放 optional 是不安全的。请考虑使用 if let 语句

请找出下面给出的答案:

 func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {

   if challenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) {


    let serverTrust:SecTrustRef = challenge.protectionSpace.serverTrust!
    let certificate: SecCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)!
    let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
    let cerPath: String = NSBundle.mainBundle().pathForResource("xyz.com", ofType: "cer")!
    let localCertificateData = NSData(contentsOfFile:cerPath)!


        if (remoteCertificateData.isEqualToData(localCertificateData) == true) {
            let credential:NSURLCredential = NSURLCredential(forTrust: serverTrust)

            challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)


            completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))

        } else {

            completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge, nil)
        }
    }
    else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate
    {

        let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")!
        let PKCS12Data = NSData(contentsOfFile:path)!


        let identityAndTrust:IdentityAndTrust = self.extractIdentity(PKCS12Data);



            let urlCredential:NSURLCredential = NSURLCredential(
                identity: identityAndTrust.identityRef,
                certificates: identityAndTrust.certArray as? [AnyObject],
                persistence: NSURLCredentialPersistence.ForSession);

            completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, urlCredential);




    }
    else
    {
        completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge, nil);
    }
  }

添加以下代码

 struct IdentityAndTrust {

    var identityRef:SecIdentityRef
    var trust:SecTrustRef
    var certArray:AnyObject
}

func extractIdentity(certData:NSData) -> IdentityAndTrust {
    var identityAndTrust:IdentityAndTrust!
    var securityError:OSStatus = errSecSuccess

    let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")!
    let PKCS12Data = NSData(contentsOfFile:path)!
    let key : NSString = kSecImportExportPassphrase as NSString
    let options : NSDictionary = [key : "xyz"]
    //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:SecIdentityRef = identityPointer as! SecIdentityRef!;
            print("\(identityPointer)  :::: \(secIdentityRef)")
            // grab the trust
            let trustPointer:AnyObject? = certEntry["trust"];
            let trustRef:SecTrustRef = trustPointer as! SecTrustRef;
            print("\(trustPointer)  :::: \(trustRef)")
            // grab the cert
            let chainPointer:AnyObject? = certEntry["chain"];
            identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray:  chainPointer!);
        }
    }
    return identityAndTrust;
}