修改添加了所需请求的精简版。
我试图在Swift 4中创建一个MacOs应用程序。此应用程序与需要RSA加密的API进行通信。
谷歌没有给出可以解释如何做到这一点的结果。 Apple关于这个主题的文档非常广泛(https://developer.apple.com/library/content/documentation/Security/Conceptual/CertKeyTrustProgGuide/KeyRead.html#//apple_ref/doc/uid/TP40001358-CH222-SW2),但仍然不是我需要的。SecKeyCopyExternalRepresentation函数给出了一个Data对象 无法转换为String。文档说它是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中是否可能?
答案 0 :(得分:1)
将二进制blob(如证书或RSA密钥)编码为字符串的常规方法是使用base64编码。您可以使用函数base64EncodedString(options:)
轻松地将Data
转换为base64。即。
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") }
答案 1 :(得分:0)
SecKeyCopyExternalRepresentation返回RSA密钥的PKCS#1格式的数据。 RSA公钥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"
现在,您可以将clientPublicKeyString发送到服务器,并期待使用PEM编码的RSA公钥。