[英]Retrieve SecKey from NSData
I encountered an issue with creating SecKey from NSData. 我从 NSData创建SecKey时遇到问题。 Basically my client-server communication is based on signature created with private key and verified on the server with public key.
基本上,我的客户端-服务器通信基于使用私钥创建的签名,并使用公钥在服务器上进行了验证。
I am implementing session transfer between two devices and in order to continue communication I need those keys to be transferred as well. 我正在实现两个设备之间的会话传输,为了继续通信,我也需要传输这些密钥。 I am converting SecKey to NSData and sending it via bluetooth, but on other side I cannot convert NSData to SecKey back to use encryption.
我将SecKey转换为NSData并通过蓝牙发送,但另一方面,我无法将NSData转换为 SecKey以使用加密。
Could you help please? 你能帮忙吗?
More complete example (swift 4, iOS 10+) - assuming you have a Base64 encoded string. 更完整的示例(swift 4,iOS 10+)-假设您具有Base64编码的字符串。 Note that the other side of the connection needs to also be creating key payloads using the same format (ie RSA - PKCS #1, also verify key size ).
请注意,连接的另一端也需要使用相同的格式来创建密钥有效载荷(即RSA-PKCS#1,还要验证密钥大小)。 This function handles public or private keys (security caveats omitted for brevity).
此功能处理公钥或私钥(为简便起见,省略了安全性警告)。
// Extract secKey from encoded string - defaults to extracting public keys
func decodeSecKeyFromBase64(encodedKey: String, isPrivate: Bool = false) -> SecKey? {
var keyClass = kSecAttrKeyClassPublic
if isPrivate {
keyClass = kSecAttrKeyClassPrivate
}
let attributes: [String:Any] =
[
kSecAttrKeyClass as String: keyClass,
kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
kSecAttrKeySizeInBits as String: 2048,
]
guard let secKeyData = Data.init(base64Encoded: encodedKey) else {
print("Error: invalid encodedKey, cannot extract data")
return nil
}
guard let secKey = SecKeyCreateWithData(secKeyData as CFData, attributes as CFDictionary, nil) else {
print("Error: Problem in SecKeyCreateWithData()")
return nil
}
return secKey
}
what I use with success ... 我成功使用的东西...
func obtainKeyData(tag: String) -> NSData? {
var keyRef: AnyObject?
let query: Dictionary<String, AnyObject> = [
String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecReturnData): kCFBooleanTrue as CFBoolean,
String(kSecClass): kSecClassKey as CFStringRef,
String(kSecAttrApplicationTag): tag as CFStringRef,
]
let result: NSData?
switch SecItemCopyMatching(query, &keyRef) {
case noErr:
result = keyRef as? NSData
default:
result = nil
}
return result
}
func insertPublicKey(publicTag: String, data: NSData) -> SecKeyRef? {
let query: Dictionary<String, AnyObject> = [
String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecClass): kSecClassKey as CFStringRef,
String(kSecAttrApplicationTag): publicTag as CFStringRef,
String(kSecValueData): data as CFDataRef,
String(kSecReturnPersistentRef): true as CFBooleanRef]
var persistentRef: AnyObject?
let status = SecItemAdd(query, &persistentRef)
if status != noErr && status != errSecDuplicateItem {
return nil
}
return obtainKey(publicTag)
}
func obtainKey(tag: String) -> SecKey? {
var keyRef: AnyObject?
let query: Dictionary<String, AnyObject> = [
String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecReturnRef): kCFBooleanTrue as CFBoolean,
String(kSecClass): kSecClassKey as CFStringRef,
String(kSecAttrApplicationTag): tag as CFStringRef,
]
let status = SecItemCopyMatching(query, &keyRef)
switch status {
case noErr:
if let ref = keyRef {
return (ref as! SecKeyRef)
}
default:
break
}
return nil
}
There is no easy way to transfer private part of the key pair( it is possible, but try to avoid it ) 没有简单的方法来转移密钥对的私有部分(有可能,但是请避免使用它)
Starting from iOS 10
you can use the following code: 从
iOS 10
开始,您可以使用以下代码:
let attributes: [String:Any] = [
kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
kSecAttrKeySizeInBits as String: blockSize,
]
secKey = SecKeyCreateWithData(secKeyData as CFData, attributes as CFDictionary, nil)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.