【发布时间】:2020-10-30 04:57:47
【问题描述】:
我是 iOS 和 Swift 的新手。我想用公钥加密一个字符串。公钥是这样的:
"-----BEGIN PUBLIC KEY-----
Some String
-----END PUBLIC KEY-----"
我搜索了一下,得到并实现了如下代码:
static func encrypt(string: String, publicKey: String?) -> String? {
guard let publicKey = publicKey else { return nil }
let keyString = publicKey.replacingOccurrences(of: "-----BEGIN PUBLIC KEY-----\n", with: "").replacingOccurrences(of: "\n-----END PUBLIC KEY-----", with: "")
guard let data = Data(base64Encoded: keyString) else { return nil }
var attributes: CFDictionary {
return [kSecAttrKeyType : kSecAttrKeyTypeRSA,
kSecAttrKeyClass : kSecAttrKeyClassPublic,
kSecAttrKeySizeInBits : 2048,
kSecReturnPersistentRef : kCFBooleanTrue] as CFDictionary
}
var error: Unmanaged<CFError>? = nil
guard let secKey = SecKeyCreateWithData(data as CFData, attributes, &error) else {
print(error.debugDescription)
return nil
}
return encrypt(string: string, publicKey: secKey)
}
static func encrypt(string: String, publicKey: SecKey) -> String? {
let buffer = [UInt8](string.utf8)
var keySize = SecKeyGetBlockSize(publicKey)
var keyBuffer = [UInt8](repeating: 0, count: keySize)
// Encrypto should less than key length
guard SecKeyEncrypt(publicKey, SecPadding.PKCS1, buffer, buffer.count, &keyBuffer, &keySize) == errSecSuccess else { return nil }
return Data(bytes: keyBuffer, count: keySize).base64EncodedString()
}
再次感谢 StackOverflow。现在的问题是我无法解密此函数返回的加密字符串。对于编码,我想要一个 2048 位的大小。 对于 Android,这就是加密的方式:
public String encryptKey() throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, CertificateException {
publicKey = getPublicKey();
Cipher oaepFromAlgo = Cipher.getInstance("RSA/NONE/OAEPWITHSHA-256ANDMGF1PADDING");
oaepFromAlgo.init(Cipher.ENCRYPT_MODE, publicKey );
//byte[] ct = oaepFromAlgo.doFinal(secretKey.toString().getBytes(StandardCharsets.UTF_8));
byte[] ct = oaepFromAlgo.doFinal(secretKey.getEncoded());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return Base64.getEncoder().encodeToString(ct);
}
else{
return android.util.Base64.encodeToString(ct,android.util.Base64.DEFAULT);
}
}
private PublicKey getPublicKey() throws CertificateException {
CertificateFactory f = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)f.generateCertificate(getTrustedCertificatesInputStream());
return certificate.getPublicKey();
}
如果有人能指导我如何解密以及我的加密过程是否类似于 android,那将非常有帮助。
【问题讨论】:
标签: ios swift iphone encryption public-key-encryption