I have Java based Web API which receives AES encrypt user credentials and let the user get the session token. This is working fine with AES encryption on client side with CryptoJS. But the same throws bad padding exception while trying to access this API from Python.
In Java I've used PKCS5Padding padding. I have tried this with NoPadding as well, but in that case the de-crypted text is simply empty. Also, when trying with NoPadding, CryptoJS code is not working properly. As, this API should work for any client side program (Later I'm planning to expand this to PHP, .Net and R as well), I want to have a common, working mechnism for encryption of passwords thru AES. I'm pretty new to python and I have tried various programs provided in stack overflow as well as in other blogs on this subject.
Here is the java part
public String decrypto(String cipherText, String secret) {
byte[] cipherData = java.util.Base64.getDecoder().decode(cipherText);
byte[] saltData = Arrays.copyOfRange(cipherData, 8, 16);
String decryptedText = null;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
final byte[][] keyAndIV = GenerateKeyAndIV(32, 16, 1, saltData, secret.getBytes(StandardCharsets.UTF_8),
md5);
SecretKeySpec key = new SecretKeySpec(keyAndIV[0], "AES");
IvParameterSpec iv = new IvParameterSpec(keyAndIV[1]);
byte[] encrypted = Arrays.copyOfRange(cipherData, 16, cipherData.length);
Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCBC.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decryptedData = aesCBC.doFinal(encrypted);
decryptedText = new String(decryptedData, StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return decryptedText;
}
And this line send the encrypted password from CrptoJS without any issues which gets de-crypted properly in Java
encKey = CryptoJS.AES.encrypt(this.logingrp.value['loginpass'], this.localPublicKey).toString();
this.localLogin(encKey);
LocalLogin is an AJAX function to call the API
Python code is below. I'm using Pycryptodome
import requests, json
import base64
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto import Random
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from hashlib import sha256
BS = 16
pad = lambda s: bytes(s + (BS - len(s) % BS) * chr(BS - len(s) % BS), 'utf-8')
unpad = lambda s : s[0:-ord(s[-1:])]
class AESCipher:
def __init__( self, key ):
self.key = bytes(key, 'utf-8')
def encrypt( self, raw ):
raw = pad(raw)
iv = Random.new().read( AES.block_size )
cipher = AES.new(self.key, AES.MODE_CBC )
return base64.b64encode( iv + cipher.encrypt( raw ) )
def decrypt( self, enc ):
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc[16:] )).decode('utf8')
header = {"Content-type": "application/json",
"Authorization": "Bearer CT9797"
}
password = 'stone@123'
keyphrase = '9DA538D0HMQXQRGI';
cipher = AESCipher(keyphrase)
encrypted = cipher.encrypt(password).decode('utf8')
payload={'userId':'CT9797','userData':encrypted,'encKey':''}
response_decoded_json = requests.post(url=_base_URL+'eLogin', data=json.dumps(payload), headers=header)
print(response_decoded_json.status_code)
The below exception occurs while trying the above program on java side
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:975)
at com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:10
Appreciate your time in reading and helping me out.