我是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,那将是非常有帮助的。
发布于 2020-07-10 11:28:28
由衷地感谢每一个试图解决这个问题的人。我设法自己完成了这件事。通过将crt文件转换为der,我将公钥提取为secKey,而不是以字符串形式表示公钥
https://stackoverflow.com/questions/62817541
复制相似问题