2
votes

I have a working Form Integration but need to move to v 3.00 of Form Integration which requires AES coding rather than Xor. The sample code is a J2EE app which hides away the method of encrypting. SagePay support have been unable to provide an API class/method for encrypting/decrypting; I suspect they are there, if anyone has used them and can advise on this?

Alternatively I am trying to do the encryption in my own code. Again SagePay have not been forthcoming, in that they don't provide enough information about how the encryption is done. I believe I have worked out that the password they provide is used both for the encryption key and iv, though they don't state this in the integration guide. Here is code I have tried for encoding inString

        byte[] byteDataToEncrypt = inString.getBytes();
        final byte[] keyBytes = webSite.encryptionPassword().getBytes("ASCII");
        final byte[] ivBytes = webSite.encryptionPassword().getBytes("ASCII");
        final SecretKey key = new SecretKeySpec(keyBytes, "AES");
        final IvParameterSpec iv = new IvParameterSpec(ivBytes);
        final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        byte[] byteCipherText = cipher.doFinal(byteDataToEncrypt);
        byte[] aesEncryptedBase64encoded = Base64.encodeBase64(byteCipherText);
            String crypt = "@" + new String(aesEncryptedBase64encoded);

I do not know why @ would need to be on the front, but I have seen it in other code that has been posted online for SagePay integration. Without it SagePay test server tells me the encryption method is not recognised. With it, it tells me the Currency field is missing, though I know the currency field is set ok to "GBP" in the source and I am using the provided test server password.

Any help very much appreciated whether from SagePay or from the developer community. John

2

2 Answers

1
votes

This works even if moving to ver4.00. The only thing that needs to be different for ver 4.00 is that it needs the encrypted string to be in upper case. Hence instead of

String crypt = "@" + Hex.encodeHexString(byteCipherText);

it will need to be

String crypt = "@" + Hex.encodeHexString(byteCipherText).toUpperCase();

Latest Sagepay/Opayo documentation at least verbally lists what all is needed and even if it is still not very comprehensive, together with this code, I could work it out. Thanks.

0
votes

The solution that worked for me is to replace this:

byte[] aesEncryptedBase64encoded = Base64.encodeBase64(byteCipherText);
String crypt = "@" + new String(aesEncryptedBase64encoded);

with this

String crypt = "@" + Hex.encodeHexString(byteCipherText);

or if using the SagePay API directly, replace all the code with just these two lines:

byte[] aesEncrypted = CryptographyHelper.AESEncrypt(detail, "ISO-8859-1", password);  
String crypt = "@" + Hex.encodeHexString(aesEncrypted);