B4J Question EncryptData Using a receiving Key- javax.crypto.BadPaddingException

M.SALIM

Member
I have to encrypt data using a key received from a service. The function below is written as per instruction given from supplier.
It crashes and giving javax.crypto.BadPaddingException: Given final block not properly padded.

Anyone kindly advise how to resolve same.
Thanking you in advance.

RECIEVED KEY: uj0rdXLW90EaoD5kMcz8ydYy0ICQGSbYCP26yDpq0BQFZCMK9cn+2plig1P2RYV9

EncryptDataUsingKey:
Sub EncryptDataUsingKey (keyReceived As String, OurData As String) As String
    Dim Cipher         As Cipher
    Dim kg              As KeyGenerator
    Dim md             As MessageDigest

    Log ("RECIEVED KEY: " & keyReceived)

    Cipher.Initialize("AES/ECB/PKCS5PADDING")
    kg.Initialize("AES")
    kg.GenerateKey
    
    'DECRYPT KEY keyReceived USING RANDOM GENERATED KEY===========
    Dim DecrytedKey()  As Byte   = Cipher.Decrypt(su.DecodeBase64(keyReceived),kg.Key    , False)
    kg.KeyFromBytes(md.GetMessageDigest(DecrytedKey ,"MD5") ) 
    
    'ENCRYPT DATA USING KEY FROM DecrytedKey =====================
    Dim NewData As String = su.EncodeBase64(Cipher.Encrypt(OurData.GetBytes("UTF8") ,kg.Key,False ))

    Log ("RANDOM  KEY: " & kg.Key)

    Return NewData
End Sub

Error occurred on line: 223 (B4XMainPage)
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:991)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
 

M.SALIM

Member
I have to encrypt data using a key received from a service. The function below is written as per instruction given from supplier.
It crashes and giving javax.crypto.BadPaddingException: Given final block not properly padded.

Anyone kindly advise how to resolve same.
Thanking you in advance.

RECIEVED KEY: uj0rdXLW90EaoD5kMcz8ydYy0ICQGSbYCP26yDpq0BQFZCMK9cn+2plig1P2RYV9

EncryptDataUsingKey:
Sub EncryptDataUsingKey (keyReceived As String, OurData As String) As String
    Dim Cipher         As Cipher
    Dim kg              As KeyGenerator
    Dim md             As MessageDigest

    Log ("RECIEVED KEY: " & keyReceived)

    Cipher.Initialize("AES/ECB/PKCS5PADDING")
    kg.Initialize("AES")
    kg.GenerateKey
   
    'DECRYPT KEY keyReceived USING RANDOM GENERATED KEY===========
    Dim DecrytedKey()  As Byte   = Cipher.Decrypt(su.DecodeBase64(keyReceived),kg.Key    , False)
    kg.KeyFromBytes(md.GetMessageDigest(DecrytedKey ,"MD5") )
   
    'ENCRYPT DATA USING KEY FROM DecrytedKey =====================
    Dim NewData As String = su.EncodeBase64(Cipher.Encrypt(OurData.GetBytes("UTF8") ,kg.Key,False ))

    Log ("RANDOM  KEY: " & kg.Key)

    Return NewData
End Sub

Error occurred on line: 223 (B4XMainPage)
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:991)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
I unable to attach the full document here as its says too big. (file is about 2mb)

Below are steps outline from the attached document:

I've been able to authenticate, but while sending the data I'm having :

{"responseId":"LT16966521855876604794462","responseDateTime":"20231007 08:16:25","requestId":"20231007_2","status":"ERROR","environment":"TEST","infoMessages":null,"errorMessages":[{"code":"ERR0200","description":"Could not decrypt invoice data"}],"fiscalisedInvoices":null}



Steps to produce the authentication JSON
1 Generate AES Symmetric Key (encryptKey) and encode key to Base 64.
2 Generate JSON corresponding to the “payload” attribute (username, password, encryptKey, refreshToken).
3 Encrypt JSON string from step 2 using MRA Public Key
4 Encode encrypted JSON from step 3 to Base 64
5 Generate JSON corresponding to the authentication request with a unique request ID
6 Call the authentication API with username and EBS MRA ID in the request header and JSON from 5 in the request body


Steps to generate JSON for invoice submission
1 Decrypt Key received from MRA using the random AES Key that was generated in the authentication step
2 Generate invoice corresponding to sample JSON invoice (MRA requested format)
3 Sign JSON in step 2 using the SHA256withRSA and the Private key of EBS downloaded during the
registration process (optional)
4 Encrypt JSON string from step 2 using decrypted Key from step 1 (Encrypted key that was received
from MRA in the authentication response parameters)
5 Generate JSON payload corresponding to the invoice transmission request
6 Call the transmission API with username, EBS MRA ID, and token in the request header
 
Upvote 0

teddybear

Well-Known Member
Licensed User
How did you encrypt the keyReceived string? it seems not to be encrypted by using AES. so you got the error :Given final block not properly padded.
 
Upvote 0

M.SALIM

Member
How did you encrypt the keyReceived string? it seems not to be encrypted by using AES. so you got the error :Given final block not properly padded.
I have rectified the coding.
Now the message sending cannot be decrypted form the other end having error :
{"responseId":"LT16968379608732180806855","responseDateTime":"20231009 11:52:40","requestId":"20231009_2","status":"ERROR","environment":"TEST","infoMessages":null,"errorMessages":[{"code":"ERR0200","description":"Could not decrypt invoice data"}],"fiscalisedInvoices":null}

kindly assist.

new coding below


B4X:
Sub EncryptRSAwithPublicKeyJSON As String
    '======================================================================================
    '1 Generate AES Symmetric Key (encryptKey) and encode key to Base 64.
    '2 Generate JSON corresponding to the “payload” attribute (username, password, encryptKey, refreshToken).
    '3 Encrypt JSON string from step 2 using MRA Public Key
    '4 Encode encrypted JSON from step 3 to Base 64
    '5 Generate JSON corresponding to the authentication request with a unique request ID
    '6 Call the authentication API with username and EBS MRA ID in the request header and JSON  from 5 in the request bodY
    
    'AES Symmetric Key =========================
    Dim r2 As String
    Dim r3 As String
    p="1234567812345678"
    'kg.KeyFromBytes(md.GetMessageDigest(p.GetBytes("UTF8"),"SHA-256"))
    kg.KeyFromBytes( p.GetBytes("UTF8") )
    enCryptKey=su.EncodeBase64(cipher.Encrypt(p.GetBytes("UTF8"), kg.Key, False))
    secukey=kg.Key
    Log("SECKey : " & secukey)
    Log("AESKey : " & enCryptKey)
    '===========================================
    'JSON  corresponding to the Payload
    objMap.Initialize
    objMap.Put("username", MYUser)
    objMap.Put("password", MYPwd )
    objMap.Put("encryptKey", enCryptKey)
    objMap.Put("refreshToken", "false")
    objJSon.Initialize (objMap)
    r2 = objJSon.ToPrettyString(5)
    Log(r2)
    
    'Encrypt JSON string from step 2 using Public Key
    Dim kpg      As KeyPairGenerator
    Dim Cipher2  As Cipher
    Cipher2.Initialize("RSA/ECB/PKCS1Padding")
    kpg.Initialize("RSA", 4096)
    kpg.PublicKeyFromBytes(su.DecodeBase64(MRA.MRAPublicKeyCert) )
    r3= su.EncodeBase64(Cipher2.Encrypt(r2.GetBytes("UTF8") ,kpg.PublicKey,False))
    '=============================================
    Log (r3.Length)
    Log (">>>" & r3)
    Return r3
End Sub

Sub EncryptDataUsingKey2023 (receivingKey As String, OurData As String) As String
    '1 Decrypt Key received from MRA using the random AES Key that was generated in the authentication step
    '  Base 64 encoded string of encrypted key. Key has been generated using AES
    '  256(AES/ECB/PKCS7Padding) algorithm And encrypted with the encryptKey present in
    '  the request payload
    '2. Generate invoice corresponding to sample JSON invoice (MRA requested format
    '3 (OPTIONAL)Sign JSON in step 2 using the SHA256withRSA and the Private key of EBS downloaded during the registration process
    '4 Encrypt JSON string from step 2 using decrypted Key from step 1 (Encrypted key that was received FROM AUTHENTICATE)
    
    Log("MYKEY :" & p)
    Log("MYKEY :" & enCryptKey)
    Log("RCVKEY:" & receivingKey)
    
    cipher.Initialize("AES/ECB/PKCS5Padding")
    kg.KeyFromBytes( su.DecodeBase64(enCryptKey) )
    secukey=kg.Key
    
    Log("KEY1: " & secukey)
    cipher.Initialize("AES/ECB/PKCS5Padding")
    'RECEIVING-KEY decode/decrypt
    Dim EKey()  As Byte   = cipher.Decrypt(  su.DecodeBase64(receivingKey)  ,secukey  , False)
    kg.KeyFromBytes(md.GetMessageDigest(EKey, "SHA-256"))
    Log("KEY2: " & kg.Key)
    
    cipher.Initialize("AES/ECB/PKCS5Padding")
    'invoice encrypt/encode
    Dim ENPInvoice As String = su.EncodeBase64(cipher.Encrypt(OurData.GetBytes("UTF8"), kg.Key,False ))   
    Log(ENPInvoice)

    Return ENPInvoice
End Sub
 
Upvote 0

teddybear

Well-Known Member
Licensed User
In your code line 65, why did you use Ekey checksum as encryptedInvoice encrypted key instead of Ekey?
 
Upvote 0

M.SALIM

Member
Please find below sample c# code received to encrypt the data:
B4X:
using (var aesAlgorithm = Aes.Create())
 {
 aesAlgorithm.Key = Convert.FromBase64String(mrakey);
 aesAlgorithm.Mode = CipherMode.ECB;
 aesAlgorithm.Padding = PaddingMode.PKCS7;
 var encryptor = aesAlgorithm.CreateEncryptor();
 byte[] encryptedData;
 //Encryption will be done in a memory stream through a CryptoStream object
 using (var ms = new MemoryStream())
 {
 using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
 {
 using (var sw = new StreamWriter(cs))
 {
 sw.Write(JsonConvert.SerializeObject(obj));
 }
 encryptedData = ms.ToArray();
 }
 }
 return Convert.ToBase64String(encryptedData);
 }

Any equivalent in b4a/b4j?
 
Upvote 0

teddybear

Well-Known Member
Licensed User
What is the key value of Authentication Response.
 
Upvote 0

teddybear

Well-Known Member
Licensed User
UxRLUvjgwsXJ9YqIFkt43V12oC7jp8ThGhnPqJhrfjmcPzHl95LO8I5+5FFwk4zl
Can you decrypt the key by the decoded enCryptKey?
You'd better post a small project can be tested in the sandbox environment
 
Upvote 0
Top