获取 SecKey 的字符串表示形式
Getting a string representation of a SecKey
编辑 添加了所需请求的屏幕截图。
我正在尝试在 Swift 4 中制作 MacOs 应用程序。此应用程序与需要 RSA 加密的 api 进行通信。
Google 没有给出可以解释如何做到这一点的结果。 Apple 关于此主题的文档相当丰富 (https://developer.apple.com/library/content/documentation/Security/Conceptual/CertKeyTrustProgGuide/KeyRead.html#//apple_ref/doc/uid/TP40001358-CH222-SW2),但仍然不是我需要的。
函数 SecKeyCopyExternalRepresentation 给出了一个数据对象
不能转换为字符串。文档说这是 PCKS #1 响应,但我无法解决。
我已经尝试了很多方法,包括下面的方法,但我无法让它工作。
func externalRepresentation(_ key: SecKey) -> String? {
var error: Unmanaged<CFError>?
guard let data = SecKeyCopyExternalRepresentation(key, &error) as Data? else {
return nil
}
return data.base64EncodedString()
}
请求需要如下:
Request
这在 Swift 中甚至可能吗?
将二进制 blob(如证书或 RSA 密钥作为字符串)编码的正常方法是使用 base64 encoding. You can convert a Data
to base64 quite easily with the function base64EncodedString(options:)
。即
let myString = myData.base64EncodedString()
很难说这是否正是您对该应用程序所需要的,因为您的问题没有提供太多上下文。
查看您的屏幕截图以及 base64 编码字符串,您需要页眉和页脚。数据结构中的大部分明显随机字母都是 base64 字符串(JSON 转换已使用 \n
对换行符进行编码,而其他内容已将反斜杠加倍)。因此,您的最后一步是在字符串前加上 -----BEGIN PUBLIC KEY-----
和一个新行,然后追加一个新行和 -----END PUBLIC KEY-----
还有一件事:您可以使用 Data.init?((base64Encoded base64String:,options:) 很容易地从 base64 字符串中取回原始数据。即
guard let myDataCopy = Data(base64Encoded: myString)
else { fatalError("the string was not really base64") }
SecKeyCopyExternalRepresentation returns RSA 密钥的 PKCS #1 格式数据。 RSA Public 密钥 PEM 文件如下所示
-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----
在 base64 编码数据中存在以下 DER 结构:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
RSA 密钥的 PKCS #1 格式应预先添加适当的“预编码”ASN.1 二进制数据结构。参考下例中的pemPrefixBuffer:
// creating client public and private key
var publicKeySec, privateKeySec: SecKey?
var error: Unmanaged<CFError>?
let keyattribute = [
kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
kSecAttrKeySizeInBits as String : 1024,
kSecAttrIsPermanent as String: false
] as CFDictionary
SecKeyGeneratePair(keyattribute, &publicKeySec, &privateKeySec)
// client public key to pem string
let keyData = SecKeyCopyExternalRepresentation(publicKeySec!, &error)
let data = keyData! as Data
let pemPrefixBuffer :[UInt8] = [
0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x03, 0x81, 0x8d, 0x00
]
var finalPemData = Data(bytes: pemPrefixBuffer as [UInt8], count: pemPrefixBuffer.count)
finalPemData.append(data)
let finalPemString = finalPemData.base64EncodedString(options: .lineLength64Characters)
let clientPublicKeyString = "-----BEGIN PUBLIC KEY-----\r\n\(finalPemString)\r\n-----END PUBLIC KEY-----\r\n"
现在您可以将客户端PublicKeyString 发送到您的服务器,期望 PEM 编码的 RSA Public 密钥。
编辑 添加了所需请求的屏幕截图。
我正在尝试在 Swift 4 中制作 MacOs 应用程序。此应用程序与需要 RSA 加密的 api 进行通信。
Google 没有给出可以解释如何做到这一点的结果。 Apple 关于此主题的文档相当丰富 (https://developer.apple.com/library/content/documentation/Security/Conceptual/CertKeyTrustProgGuide/KeyRead.html#//apple_ref/doc/uid/TP40001358-CH222-SW2),但仍然不是我需要的。
函数 SecKeyCopyExternalRepresentation 给出了一个数据对象 不能转换为字符串。文档说这是 PCKS #1 响应,但我无法解决。
我已经尝试了很多方法,包括下面的方法,但我无法让它工作。
func externalRepresentation(_ key: SecKey) -> String? {
var error: Unmanaged<CFError>?
guard let data = SecKeyCopyExternalRepresentation(key, &error) as Data? else {
return nil
}
return data.base64EncodedString()
}
请求需要如下: Request
这在 Swift 中甚至可能吗?
将二进制 blob(如证书或 RSA 密钥作为字符串)编码的正常方法是使用 base64 encoding. You can convert a Data
to base64 quite easily with the function base64EncodedString(options:)
。即
let myString = myData.base64EncodedString()
很难说这是否正是您对该应用程序所需要的,因为您的问题没有提供太多上下文。
查看您的屏幕截图以及 base64 编码字符串,您需要页眉和页脚。数据结构中的大部分明显随机字母都是 base64 字符串(JSON 转换已使用 \n
对换行符进行编码,而其他内容已将反斜杠加倍)。因此,您的最后一步是在字符串前加上 -----BEGIN PUBLIC KEY-----
和一个新行,然后追加一个新行和 -----END PUBLIC KEY-----
还有一件事:您可以使用 Data.init?((base64Encoded base64String:,options:) 很容易地从 base64 字符串中取回原始数据。即
guard let myDataCopy = Data(base64Encoded: myString)
else { fatalError("the string was not really base64") }
SecKeyCopyExternalRepresentation returns RSA 密钥的 PKCS #1 格式数据。 RSA Public 密钥 PEM 文件如下所示
-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----
在 base64 编码数据中存在以下 DER 结构:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
RSA 密钥的 PKCS #1 格式应预先添加适当的“预编码”ASN.1 二进制数据结构。参考下例中的pemPrefixBuffer:
// creating client public and private key
var publicKeySec, privateKeySec: SecKey?
var error: Unmanaged<CFError>?
let keyattribute = [
kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
kSecAttrKeySizeInBits as String : 1024,
kSecAttrIsPermanent as String: false
] as CFDictionary
SecKeyGeneratePair(keyattribute, &publicKeySec, &privateKeySec)
// client public key to pem string
let keyData = SecKeyCopyExternalRepresentation(publicKeySec!, &error)
let data = keyData! as Data
let pemPrefixBuffer :[UInt8] = [
0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x03, 0x81, 0x8d, 0x00
]
var finalPemData = Data(bytes: pemPrefixBuffer as [UInt8], count: pemPrefixBuffer.count)
finalPemData.append(data)
let finalPemString = finalPemData.base64EncodedString(options: .lineLength64Characters)
let clientPublicKeyString = "-----BEGIN PUBLIC KEY-----\r\n\(finalPemString)\r\n-----END PUBLIC KEY-----\r\n"
现在您可以将客户端PublicKeyString 发送到您的服务器,期望 PEM 编码的 RSA Public 密钥。