I was trying to convert a java
code to python
. tried to use pycryptodome
library for the purpose. This is java
code:
try {
String data= "shouldEncryptDATA";
String bas64ed= "";
int len12 = Integer.parseInt("12");
byte[] randomparam= new byte[len12];
new SecureRandom().nextBytes(randomparam);
SecretKeySpec secretKeySpec= new SecretKeySpec("1f1f7892GKG38815".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(1, secretKeySpec, new GCMParameterSpec(Integer.parseInt("16") * 8, randomparam));
byte[] bytedata= cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
byte[] newbytearray= new byte[bytedata.length + len12];
System.arraycopy(randomparam, 0, newbytearray, 0, len12);
System.arraycopy(bytedata, 0, newbytearray, len12, bytedata.length);
bas64ed= Base64.getEncoder().encodeToString(newbytearray);
System.out.println("bas64ed: "+bas64ed);
System.out.println(URLEncoder.encode(bas64ed, "UTF-8"));
} catch (Exception unused_ex) {
System.out.println();
System.out.println("ERROR: " + unused_ex);
}
so far I tried below python
code to mimic above java
code:
import base64
from Crypto.Cipher import AES
import urllib.parse
from Crypto.Random import get_random_bytes
data= "shouldEncryptDATA"
key = b '1f1f7892GKG38815'
len12 = 12
v1 = bytearray(len12)
cipher = AES.new(key, AES.MODE_GCM, nonce=get_random_bytes(12) )
ciphertext, tag = cipher.encrypt_and_digest(data.encode("utf8"))
base64ed = ""
for x in cipher.nonce, ciphertext, tag:
base64ed += base64.b64encode(x).decode('utf-8')
urlencoded = urllib.parse.quote_plus(base64ed+"\n")
print(urlencoded )
the above python
code generates an output
but the problem is that when I supply the output to the decryption
code I got MAC check Failed
. so I realized my implementation in the python
code is somewhat is the problem because the output of the Java
code when passed to the decryption
code, it works and decrypts the data. so How can I correctly convert the Java
encryption code to Python
? using the Pycryptodome
or any other suitable library.
The bug in the Python code is in the concatenation, it must be:
base64ed = base64.b64encode(cipher.nonce + ciphertext + tag).decode('utf-8')
After this fix, if you compare the ciphertexts of both codes with identical input data (especially with identical IV), they are the same.