Reputation: 9
Using the below lines of code for Encrypting and Decrypting using BouncyCastle for decrypting data received from a 3rd party source based on C. First encryption and decryption works fine(basis the initial key and iv shared by the 3rd party which they have asked to use through out the session), second encryption and decryption fails.. mostly because I am using the same IV again if you notice. Looking for what might be the logic for the new IV creation and how am i supposed to send it to the 3rd party (if i do not send it, how can they decrypt without knowing the created IV)
public byte[] encrypt(byte[] plainBytes) {
byte[] encryptedBytes = new byte[0];
try {
GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
AEADParameters parameters =
new AEADParameters(new KeyParameter(key), MacBitSize, iv);
cipher.init(true, parameters);
encryptedBytes = new byte[cipher.getOutputSize(plainBytes.length)];
int retLen = cipher.processBytes
(plainBytes, 0, plainBytes.length, encryptedBytes, 0);
cipher.doFinal(encryptedBytes, retLen);
} catch (IllegalArgumentException |
IllegalStateException | DataLengthException |
InvalidCipherTextException ex) {
System.out.println(ex.getMessage());
}
System.arraycopy(aad, 0, encryptedBytes, plainBytes.length, 16);
byte[] final_encr = new byte[plainBytes.length];
System.arraycopy(encryptedBytes, 0, final_encr, 0, plainBytes.length);
return final_encr;
}
public byte[] decrypt(byte[] encryptedBytes) {
byte[] plainBytes = new byte[0];
try {
GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
AEADParameters parameters =
new AEADParameters(new KeyParameter(key), MacBitSize, iv);
cipher.init(false, parameters);
cipher.processAADBytes(aad, 0, aad.length);
plainBytes = new byte[encryptedBytes.length];
int retLen = cipher.processBytes
(encryptedBytes, 0, encryptedBytes.length, plainBytes, 0);
retLen += cipher.processBytes(aad, 0, aad.length, plainBytes, retLen);
retLen += cipher.doFinal(plainBytes, retLen);
} catch (IllegalArgumentException | IllegalStateException |
DataLengthException | InvalidCipherTextException ex) {
System.out.println(ex.getMessage());
}
return plainBytes;
}
Methodology provided by third party in the doc
For symmetric encryption/decryption methodology –
Encryption:
Initialization →
void encrypt_EVP_aes_256_cbc_init(EVP_CIPHER_CTX ** ctx, unsigned char * key,
unsigned char * iv) {
if (!( * ctx = EVP_CIPHER_CTX_new()))
handleErrors();
if (1 != EVP_EncryptInit_ex( * ctx, EVP_aes_256_gcm(), NULL, key, iv))
handleErrors();
}
Encryption →
void encrypt(EVP_CIPHER_CTX * ctx, unsigned char * plaintext, int plaintext_len,
unsigned char * ciphertext, int * ciphertext_len) {
int len;
if (1 != EVP_EncryptUpdate(ctx, ciphertext, & len, plaintext, plaintext_len))
handleErrors();
* ciphertext_len = len;
}
Decryption:
Initialization→
void decrypt_EVP_aes_256_cbc_init(EVP_CIPHER_CTX ** ctx, unsigned char * key,
unsigned char * iv) {
if (!( * ctx = EVP_CIPHER_CTX_new()))
handleErrors();
if (1 != EVP_DecryptInit_ex( * ctx, EVP_aes_256_gcm(), NULL, key, iv))
handleErrors();
}
Decryption→
int decrypt(EVP_CIPHER_CTX * ctx, unsigned char * ciphertext, int ciphertext_len,
unsigned char * plaintext, int * plaintext_len) {
int len;
if (1 != EVP_DecryptUpdate(ctx, plaintext, & len, ciphertext, ciphertext_len))
handleErrors();
* plaintext_len = len;
}
Note –
Upvotes: 0
Views: 147
Reputation: 25
Take a look at the parts of the encryption and decryption:
In encrypt you add the aad
System.arraycopy(aad, 0, encryptedBytes, plainBytes.length, 16);
in decrypt you do not use these data
cipher.processAADBytes(aad, 0, aad.length);
Please update your code, that no global variables are used.
May [16 byte AAD || 12 byte IV || ciphertext]
be a good output for encrypt for you? At decrypt read aad, then iv, then perform decryption.
Use inputstream and outputstream for simple read and write.
Upvotes: 1