【发布时间】:2020-08-24 07:34:10
【问题描述】:
请指导我。我在解密由 iOS“AES/CBC/PKCS7Padding”加密的字符串时遇到问题。它抛出异常。我想在android中解密字符串,在ios中加密。
在 Android 中,我遵循以下结构:
For Example:
String text = "rzp_test_DezQO1BVMXhkZY";
String key = "5b0904cfada01b8182bcc029b928244d"; // secret key - 128 bit key
String iv_key ="c999cbd1f130db1d";
我想加密和解密上面提到的“文本”字符串。如果我只从 Android 进行加密和解密。然后它工作正常。但是如果我试图解密在 ios 中加密的密钥,那么它会引发错误。
// Create key and cipher
Cipher dcipher, d1cipher;
IvParameterSpec ivSpec = new IvParameterSpec(iv_key.getBytes());
Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
ecipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
dcipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
ecipher.init(ENCRYPT_MODE, aesKey, ivSpec);
dcipher.init(DECRYPT_MODE, aesKey, ivSpec);
加密算法:
public String encrypt(String str) throws Exception {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = ecipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return Base64.encodeToString(enc, Base64.DEFAULT);
}
解密算法:
public String decrypt(String str) throws Exception {
// Decode base64 to get bytes
String decrypted = "";
try {
byte[] dec = Base64.decode(str, Base64.DEFAULT);
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
decrypted = new String(utf8, "UTF8").trim();
} catch (Exception e) {
e.printStackTrace();
}
return decrypted;
}
它在 Android 中的加密和解密都可以正常工作。用这个检查:
String encrypted = encrypt(text);
System.out.println("Encrypted String: " + encrypted);
String decrypted = decrypt(encrypted);
System.out.println("Decrypted String: " + decrypted);
问题在于从 ios 解密以下加密字符串,这会引发错误:
String decrypted1 = decrypt("c7076c78fc5d9d92c1d86c1500dcc0366ddf1b6e32df00ceadc911239935460d");
System.out.println("Decrypted String1: " + decrypted1);
错误是:
W/System.err: javax.crypto.BadPaddingException: error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT
W/System.err: at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
W/System.err: at com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER.doFinalInternal(OpenSSLCipher.java:570)
W/System.err: at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:351)
W/System.err: at javax.crypto.Cipher.doFinal(Cipher.java:1741)
W/System.err: at com.example.aesencryption.Activities.MainActivity1.decrypt(MainActivity1.java:178)
有人可以指导我吗??
在IOS中:
使用以下函数。
func aesEncrypt() -> String {
let iv: [UInt8] = Array(AES_IV.utf8)
let key: [UInt8] = Array(AES_SECRET.utf8)
do{
let encrypted = try AES (key: key, blockMode: CBC(iv: iv)).encrypt([UInt8](self.data(using: .utf8)!))
return Data(encrypted).base64EncodedString()
}
catch{
print("error on encrypting data ")
return ""
}
}
func aesDecrypt() -> String {
let iv: [UInt8] = Array(AES_IV.utf8)
let key: [UInt8] = Array(AES_SECRET.utf8)
do{
guard let data = Data(base64Encoded: self) else { return "" }
let decrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt([UInt8](data))
return String(bytes: decrypted, encoding: .utf8) ?? self
}
catch{
print("error on encrypting data ")
return ""
}
}
【问题讨论】:
-
iOS 是否使用相同的
PKCS7Padding进行加密? -
iOS 密文是十六进制编码的。但是,Android 代码中的
decrypt需要 Base64 编码的字符串(因为encryptBase64 对密文进行编码)。所以你有两种可能性:要么将 iOS 密文转换为 Base64,例如Base64.encodeToString(hexStringToByteArray("c707...460d"), Base64.DEFAULT);和hexStringToByteArray来自 here 或者您相应地修改 Android 代码(以便也应用十六进制编码)。 -
另外,使用了 AES-256(而不是 AES-128)。
-
@RodrigoQueiroz 我添加了 iOS 算法。请看一看。
-
@topaco,我添加了 iOS 算法。请看一看。
标签: android encryption cryptography aes