-1

I am trying to integrate payment gateway into salesforce site, i have used the AES128 Encryption and same is use for decryption but while decryption i have used java code where i got the decrypt value as below

Output value :- "1\u000e\u0018\u001a7y&6-u:^@&/$3d87caf26f3daa75fbbef54a3ca48480676c828950be0db54JN5"

Expected Value:-

"4697a3e0a09423933d87caf26f3daa75fbbef54a3ca48480676c828950be0db54JN5"

Apex code for encryption:-

public String encrypt() {
    String encryptedString = '';
    Blob exampleIv = Blob.valueOf('Example of IV123');
    Blob crypto128Key = Blob.valueOf('r2AAAh9Z8AXvdey9');
    Blob dataToBeEncryptedAsBlob = Blob.valueOf('4697a3e0a09423933d87caf26f3daa75fbbef54a3ca48480676c828950be0db54JN5');
    try {
        Blob returnCipher = Crypto.encrypt('AES128', crypto128Key, exampleIv, dataToBeEncryptedAsBlob);
        encryptedString = EncodingUtil.base64Encode(returnCipher);
        Blob encryptedVal = EncodingUtil.base64Decode(encryptedString);
    } catch (Exception e) {
       System.debug('Error in encrypt -->'+e);
    }
    return encryptedString;
}

Java code for decryption: -

private final BASE64Encoder base64Encoder = new BASE64Encoder();
private final BASE64Decoder base64Decoder = new BASE64Decoder();

private final byte[] ivParamBytes = { 64, 64, 64, 64, 
   38, 38, 38, 38, 
   35, 35, 35, 35, 
   36, 36, 36, 36 };

public String decrypt(String toDecrypt, String key) throws Exception
  {
    String decryptedValue = "";

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING", "SunJCE");
    cipher.init(2, new SecretKeySpec(key.getBytes(), "AES"), new IvParameterSpec(ivParamBytes));
    decryptedValue = new String(cipher.doFinal(base64Decoder.decodeBuffer(toDecrypt)));
    return decryptedValue;
  }
1
  • 2
    FYI all, marked the other (older) post as a duplicate since David has posted a good answer to this one.
    – Matt Lacey
    Commented Mar 25, 2019 at 23:34

2 Answers 2

2

I see several issues or potential issues here.

Blob exampleIv = Blob.valueOf('Example of IV123');

This is definitely wrong. In Java, you have hard-coded an initialization vector as a byte string:

private final byte[] ivParamBytes = { 64, 64, 64, 64, 
   38, 38, 38, 38, 
   35, 35, 35, 35, 
   36, 36, 36, 36 };

If you want the same results in Apex, you'll have to use the same initialization vector.

N.b. hard-coding a constant initialization vector is a pretty bad idea security-wise. You generally don't want multiple encryptions of the same value to yield the same ciphertext - that makes the whole shebang vulnerable to lots of exciting attacks the mathematical details of which I am not qualified to explain. It's also not the right way to test interoperability of two cryptosystems or implementations - you should just be checking that each can decrypt values encrypted by the other.

In Apex, you'll probably want to store this initialization vector as a hexadecimal string and convert it to a binary blob with EncodingUtil.convertFromHex(). Then you can supply it to encrypt().

You haven't supplied very much information about how you've tested this code, but I suspect what you're seeing in your output - some binary nonsense bytes, followed by the end of your real plaintext - reflects the problem with your IV. You're essentially corrupting the first block of your text.

See this question on Stack Overflow for more about how Cipher Block Chaining mode reacts to data corruption, which is what you've accidentally introduced here.

Other Issues

Blob crypto128Key = Blob.valueOf('r2AAAh9Z8AXvdey9');
Blob dataToBeEncryptedAsBlob = Blob.valueOf('4697a3e0a09423933d87caf26f3daa75fbbef54a3ca48480676c828950be0db54JN5');

This is likely to be wrong. Blob.valueOf() doesn't convert encoded data, like hex or Base64. It just creates a blob containing the literal string value.

It's not totally clear to me what these values are - the second one is mostly but not entirely hexadecimal - but if they're anything other than literal ASCII, Blob.valueOf() is not the right way to handle the data. r2AAAh9Z8AXvdey9 is 16 ASCII bytes or 128 bits, but that's not a typical representation of a raw cryptographic key.

Basically, the problems here are mostly cryptography, not Apex. Crypto is really easy to get wrong, and you need to understand how it works in order to implement it correctly even at a basic level.

1
  • Thanks for your answer I am able to solve the issue as my initialization vector does not match Commented Mar 26, 2019 at 6:40
0

I found the solution for the issue as the initialization vector is different than i am using.

I used to match the vector in apex same as java by using the below method in the link Integer Array to Base64 String

Thanks.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .