【问题标题】:exporting a public key generated by SecKeyGeneratePair using SecItemCopyMatching swift 2.0使用 SecItemCopyMatching swift 2.0 导出 SecKeyGeneratePair 生成的公钥
【发布时间】:2016-05-04 19:23:57
【问题描述】:

使用 Swift 2.2;在 El Capitan 下运行的 Xcode 7.3.1

使用 SecKeyGeneratePair 创建了一个私钥/公钥对 使用此代码获得了我的公钥的副本......然后我对其进行编码,以便我可以通过蓝牙链接发送它。

internal func generateKeyPair(publicKeyTag: String, privateKeyTag:String, keySize: Int)   {

    let privateKeyAttr: [NSString: AnyObject] = [
        kSecAttrIsPermanent: true,
        kSecAttrApplicationTag: privateKeyTag.dataUsingEncoding(NSUTF8StringEncoding)!
    ]
    let publicKeyAttr: [NSString: AnyObject] = [
        kSecAttrIsPermanent: true,
        kSecAttrApplicationTag: publicKeyTag.dataUsingEncoding(NSUTF8StringEncoding)!
    ]
    let parameters: [NSString: AnyObject] = [
        kSecAttrKeyType: kSecAttrKeyTypeRSA,
        kSecAttrKeySizeInBits: keySize,
        kSecPrivateKeyAttrs: privateKeyAttr,
        kSecPublicKeyAttrs: publicKeyAttr
    ]

    let result = SecKeyGeneratePair(parameters, &publicKey, &privateKey)

   if errSecSuccess != result {
        print("generateKeyPair fail",errSecSuccess, result)
   } else {
       //print("\(publicKey)\n\n","\(privateKey)")

    var dataPtr: AnyObject?
    let query: [NSString:AnyObject] = [
        kSecClass: kSecClassKey,
        kSecAttrApplicationTag: publicKeyTag.dataUsingEncoding(NSUTF8StringEncoding)!,
        kSecReturnData: true
    ]
    let qResult = SecItemCopyMatching(query, &dataPtr)
    if (qResult == errSecSuccess) {
        let PublicKeyText = dataPtr as? NSData
        base64Encoded = PublicKeyText!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
        print("PublicKeyText \(base64Encoded)")
    }
    }
}

现在我可以使用此代码对我的 base64EncodedString blob 进行未编码 ...

 let data = NSData(base64EncodedString: superString8, options:   NSDataBase64DecodingOptions(rawValue:0))

但是如何使用 Swift 将其恢复为可用的 SecKey 对象?我找到了这个参考并开始翻译它;但我担心我在这里超出了我的深度?

get SecKeyRef from base64 coded string

这是我到目前为止所管理的..

      let cert:SecCertificateRef!
            let policy:SecPolicyRef!
            cert = SecCertificateCreateWithData(kCFAllocatorDefault, data!)
            policy = SecPolicyCreateBasicX509();
            //var status:OSStatus!
            var publicKey: SecKeyRef!
            //var publicKeyPtr = withUnsafeMutablePointer(&publicKey, { $0 })
            var trust:SecTrust?
            let trustPtr = withUnsafeMutablePointer(&trust , { $0} )
            var certArray:[SecCertificateRef] = []
            certArray.append(cert)

            var unsafeVariable:UnsafePointer<Void>

            let certArrayPtr = withUnsafeMutablePointer(&unsafeVariable, {$0})
            var newTrustType: SecTrustResultType = UInt32(kSecTrustResultInvalid)
            let newTrustTypePtr = withUnsafeMutablePointer(&newTrustType, {$0})

            if (cert != nil) {
                //certArray[1] = {cert}()
               // let certs:[SecCertificateRef] = CFArrayCreate(kCFAllocatorDefault, certArrayPtr, 1, nil) as! [SecCertificateRef]
                let certs:[SecCertificateRef] = CFArrayCreate(kCFAllocatorDefault, certArrayPtr, 1, nil) as! [SecCertificateRef]
                var status = SecTrustCreateWithCertificates(certs, policy, trustPtr)
                if (status == errSecSuccess){
                    //status = SecTrustEvaluate(trust!, trustTypePtr)
                      status = SecTrustEvaluate(trust!, newTrustTypePtr)
                    // Evaulate the trust.
                   switch (Int(newTrustType)) {
                   case kSecTrustResultInvalid: break
                   case kSecTrustResultDeny: break
                   case kSecTrustResultUnspecified: break
                   case kSecTrustResultFatalTrustFailure: break
                   case kSecTrustResultOtherError: break
                    case kSecTrustResultRecoverableTrustFailure:
                        publicKey = SecTrustCopyPublicKey(trust!);
                        break;
                    case kSecTrustResultProceed:
                        publicKey = SecTrustCopyPublicKey(trust!);
                        break;
                    }

                }
            }
        } else {
            superString8 = superString8 + stringFromData!
        }
    }

【问题讨论】:

  • 该错误来自代码的哪一行,同样在您的屏幕截图中,您的错误消息是 trunca...
  • 显示的错误信息来自定义 CertArrayPtr...的行...

标签: ios swift encryption seckeyref


【解决方案1】:

试试这样的:

    let certArrayPtr = withUnsafeMutablePointer(&certArray, {$0})
    var newTrustType: SecTrustResultType = UInt32(kSecTrustResultInvalid)
    let newTrustTypePtr = withUnsafeMutablePointer(&newTrustType, {$0})

    if (cert != nil) {
        certArray[1] = {cert}()
        let certs = CFArrayCreate(kCFAllocatorDefault, unsafeBitCast(certArrayPtr, UnsafeMutablePointer<UnsafePointer<Void>>.self), 1, nil) as! [SecCertificateRef]

(这里的第一行和最后一行是不同的……certArrayPtr 不需要成为varunsafeBitCast 很恶心,但它应该能让你克服障碍;我在this related question 找到了它)。

【讨论】:

  • 哇,非常感谢;它编译了,现在进行酸性测试它是否有效!
  • 迈克尔,投票,因为它编译;但遗憾的是不起作用。似乎 SeccertificateCreateWithData 无法创建任何东西,它只是返回一个 nil。将代码移植回发送公钥的客户端以排除蓝牙 base64 会话和传输。
猜你喜欢
  • 2015-03-07
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 2017-09-24
  • 2012-10-07
  • 2017-11-02
  • 2011-07-11
  • 1970-01-01
相关资源
最近更新 更多