Guide me on this. I am facing problem with decryption of string which is encrypted by iOS "AES/CBC/PKCS7Padding". It throws exception. I want to decrypt string in android, which is encrypted in ios.
In Android i am following this structure:
For Example:
String text = "rzp_test_DezQO1BVMXhkZY";
String key = "5b0904cfada01b8182bcc029b928244d"; // secret key - 128 bit key
String iv_key ="c999cbd1f130db1d";
I want to encrypt and decrypt 'text' string mentioned above. If i do encryption and decryption from Android only. then its working fine. but if i tried to decrypt key which is encrypted in ios then it throws errors.
// 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);
Encryption Algo:
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);
}
Decryption Algo:
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;
}
Its working fine in Android for both Encryption and Decryption. Check with this:
String encrypted = encrypt(text);
System.out.println("Encrypted String: " + encrypted);
String decrypted = decrypt(encrypted);
System.out.println("Decrypted String: " + decrypted);
Problem is with decrypting below encrypted string from ios, This Throws error:
String decrypted1 = decrypt("c7076c78fc5d9d92c1d86c1500dcc0366ddf1b6e32df00ceadc911239935460d");
System.out.println("Decrypted String1: " + decrypted1);
Error is:
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)
Anyone can please guide me on this??
In IOS:
Following functions are used.
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 ""
}
}
PKCS7Padding
to encrypt? – Rodrigo Queirozdecrypt
in the Android code expects a Base64 encoded string (becauseencrypt
Base64 encodes the ciphertext). So you have two possibilities: Either you convert the iOS-ciphertext to Base64, e.g.Base64.encodeToString(hexStringToByteArray("c707...460d"), Base64.DEFAULT);
withhexStringToByteArray
from here or you modify the Android code accordingly (so that also a hexadecimal encoding is applied). – Topaco