在iOS(Swift)中生成后获取RSA密钥对作为字符串?

Posted

技术标签:

【中文标题】在iOS(Swift)中生成后获取RSA密钥对作为字符串?【英文标题】:Get RSA key pair as String after generating in iOS (Swift)? 【发布时间】:2017-01-17 09:11:26 【问题描述】:

ios 中生成 RSA 密钥对并将其作为 String 获取的最佳方式是什么?我见过几个可以生成的库,但我无法将私钥作为字符串。有谁知道在字符串中获取私钥的库或方法?

目前我以这种方式生成密钥对

var statusCode: OSStatus
var publicKey: SecKey?
var privateKey: SecKey?

let publicKeyAttr: [NSObject: NSObject] = [kSecAttrIsPermanent:true as NSObject, kSecAttrApplicationTag:"publicTag" as NSObject]
let privateKeyAttr: [NSObject: NSObject] = [kSecAttrIsPermanent:true as NSObject, kSecAttrApplicationTag:"privateTag" as NSObject]

var keyPairAttr = [NSObject: NSObject]()
keyPairAttr[kSecAttrKeyType] = kSecAttrKeyTypeRSA
keyPairAttr[kSecAttrKeySizeInBits] = 2048 as NSObject?
keyPairAttr[kSecPublicKeyAttrs] = publicKeyAttr as NSObject?
keyPairAttr[kSecPrivateKeyAttrs] = privateKeyAttr as NSObject?

statusCode = SecKeyGeneratePair(keyPairAttr as CFDictionary, &publicKey, &privateKey)

if statusCode == noErr && publicKey != nil && privateKey != nil 

    print(publicKey!)
    print(privateKey!)

 else 
  print("Error generating key pair: \(statusCode)")

它在 SecKey 中。如何将它们转换为 String?或者有其他方法吗?

【问题讨论】:

Generate an RSA public / private key pair的可能重复 @OlegGordiichuk 它没有提到如何获取字符串中的私钥。 看看SecItemCopyMatching。我知道你可以获得公钥的原始数据。我希望它也适用于私钥。获得数据后,您可以对其进行 Base64 编码。 【参考方案1】:

这是使用SecItemCopyMatching的代码:

let PublicKeyTag = "publicTag"
let PrivateKeyTag = "privateTag"

let publicKeyAttr: [NSString: Any] = [
    kSecAttrIsPermanent: NSNumber(value: true),
    kSecAttrApplicationTag: PublicKeyTag
]
let privateKeyAttr: [NSString: Any] = [
    kSecAttrIsPermanent: NSNumber(value: true),
    kSecAttrApplicationTag: PrivateKeyTag
]

let keyPairAttr: [NSString: Any] = [
    kSecAttrKeyType: kSecAttrKeyTypeRSA,
    kSecAttrKeySizeInBits: 2048 as NSObject,
    kSecPublicKeyAttrs: publicKeyAttr,
    kSecPrivateKeyAttrs: privateKeyAttr
]

var publicKey: SecKey?
var privateKey: SecKey?
var statusCode: OSStatus
statusCode = SecKeyGeneratePair(keyPairAttr as CFDictionary, &publicKey, &privateKey)

if statusCode == noErr && publicKey != nil && privateKey != nil 
    print(publicKey!)
    print(privateKey!)
 else 
    print("Error generating key pair: \(statusCode)")


var dataPtr: AnyObject?
let query: [NSString: Any] = [
    kSecClass: kSecClassKey,
    kSecAttrApplicationTag: PrivateKeyTag,
    kSecReturnData: NSNumber(value: true)
]
statusCode = SecItemCopyMatching(query as CFDictionary, &dataPtr)

let privateKeyData = dataPtr as! Data
let privateKeyString = privateKeyData.base64EncodedString(options: [])
print(privateKeyString)

privateKeyData 似乎包含 ASN.1 编码信息。最终结果是 Base64 编码的。

【讨论】:

【参考方案2】:

如果对任何人有帮助,请尝试以下方法。 使用 SecKey 类型的输入参数在代码中添加以下方法。

 func secKeyToString(key:SecKey) 
        var error:Unmanaged<CFError>?
        if let cfData = SecKeyCopyExternalRepresentation(key, &error) 
            let base64KeyString = (cfData as Data).base64EncodedString()
            print("Sec key in string:\(base64KeyString)")
        
    

您还可以使用相同的代码库创建 SecKey 类的扩展,并返回 base 64 编码字符串,如下所示: 扩展 SecKey

    func toString()-> String
        var error:Unmanaged<CFError>?
        let cfData = SecKeyCopyExternalRepresentation(self, &error)
        let base64KeyString = (cfData as! Data).base64EncodedString()
        return base64KeyString
    

使用方法如下:

//publicSecKey is your public key in SecKey format
let keyInStringFormat = publicSecKey.toString()
print("public key in string:\(keyInStringFormat)")

【讨论】:

以上是关于在iOS(Swift)中生成后获取RSA密钥对作为字符串?的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中生成 PKCS#1 格式的 RSA 密钥

RSA加密公钥系数获取结果多00

使用Thales nShield HSM的PKCS11interop c#wrapper库导出/导入RSA密钥对?

如何从字符串获取 PKCS8 RSA 私钥/从 XML 获取 RSA 密钥对

iOS 生成 RSA 非随机密钥对?

在 Mono C# 中生成密钥对并使用此加密数据