Swift 3如何将SecKey导出为字符串?

9
我正在使用Swift 3开发iOS应用程序。 我需要导出一个SecKey(用户RSA公钥引用),以字符串形式(例如base64)共享它,以便通过生成的QRCode传递给其他人。同时,该方式也需要可逆转,扫描QRCode的其他用户可以从QRCode提取的字符串中重建SecKey引用。我找到了一些教程,但我不知道如何从SecKey引用中提取我需要的内容,也不知道如何将其转换为String。请帮我处理一下这个问题。

你能将SecKey转换为Data吗?一旦你有了Data,获取base64字符串就很容易了。 - rmaddy
你真的需要使用那个棘手的 SecKey 类吗?在阅读了这个详细的问题之后,我认为这并不容易被绕过 :-( - Paulo Mattos
很遗憾,是的。我正在使用的加密库需要一个SecKey对象,因为我正在从应用程序中生成这些密钥。 - Scaraux
1个回答

24

导出密钥(仅适用于iOS 10)

var error:Unmanaged<CFError>?
if let cfdata = SecKeyCopyExternalRepresentation(publicKey!, &error) {
   let data:Data = cfdata as Data
   let b64Key = data.base64EncodedString()
}

请参考https://dev59.com/pIbca4cB1Zd3GeqPXZLq#30662270https://stackoverflow.com/a/27935528/5276890了解更长的方法,这些方法可能支持 iOS < 10。

重新导入密钥

guard let data2 = Data.init(base64Encoded: b64Key) else {
   return
}

let keyDict:[NSObject:NSObject] = [
   kSecAttrKeyType: kSecAttrKeyTypeRSA,
   kSecAttrKeyClass: kSecAttrKeyClassPublic,
   kSecAttrKeySizeInBits: NSNumber(value: 512),
   kSecReturnPersistentRef: true as NSObject
]

guard let publicKey = SecKeyCreateWithData(data2 as CFData, keyDict as CFDictionary, nil) else {
    return
}

注意:这会生成一个base64密钥而不是证书。很多在线代码示例涉及如何使用SecCertificateCreateWithData从证书生成公钥。

另外:512位的密钥生成速度快但毫无价值。一旦您对结果感到满意,请选择更长且更安全的值。

我导入并导出生成的密钥时得到了有效的结果,所以我认为它可以工作,但我没有尝试使用它进行加密和解密。


明天我会尝试。在重新导入时,cfdata是base64字符串吗? - Scaraux
抱歉,我有点懒,没有生成字符串数据和从数据生成CFData。你能应付吗?否则,我将在今天稍后尝试添加代码。 - Roy Falk
没关系,我刚刚编辑了代码。该死的5分钟评论限制! - Roy Falk
谢谢,它可以用于导出公钥字符串,我也可以重复使用它来导出私钥。 - Medhi
还有苹果官方文档介绍如何在 SecKeyData 之间进行转换:https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_as_data - Nickkk
@Nickkk 这个问题已经六年了。作为回答这个问题的人,我不记得当时有这个文档存在。而且,Swift 当时正在快速发展。如果我没记错,Swift 2 和 3 差别很大。只有在版本 4 和 5 中才慢下来。 - Roy Falk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接