使用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!
}
}
答案 0 :(得分: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
不需要成为var
,而unsafeBitCast
是粗略的,但它应该让你超越障碍;我在this related question)中找到了它。