0

For legacy compatibility I am being tasked with taking a 40 character value and adding 00000000 to the end and encrypting using RC2 in CBC Mode. I've been provided a 20 character key to use for encryption and a stand alone tool, written in Java, already being used to encrypt one 48 character string at a time. I am writing a script that will iterate through the list of 48 character values, encrypt each one, and then write it back to a table. I've tried to follow the Java code to replicate the process but am not getting the same results. Any help would be appreciated. Currently there is just one 48 character value in the list of values for testing. Later it will be pointed at an Oracle table for input and output:

value: e134db7b54ac00cb4236bb1be093e555613a54a600000000

key: 4757A2501EF662FD4C62

Python Result: EE2FCB7440EF47E55D4C01E8FCFF0069FB31438C4D69CA54

Java Result: F05CD7CD8906548C9B9FA2489D0B80A090BCF1D24FCE425B

Python:

from Cryptodome.Cipher import ARC2

values = ['e134db7b54ac00cb4236bb1be093e555613a54a600000000']

for value in values:

    value = bytearray(value, 'ascii').decode('hex')
    key = bytearray('4757A2501EF662FD4C62', 'ascii').decode('hex')
    iv = '\x00\x00\x00\x00\x00\x00\x00\x00'
    ef_keylen = 80

    cipher = ARC2.new(key, ARC2.MODE_CBC, iv=iv, effective_keylen=ef_keylen)

    encryptedvalue = cipher.encrypt(value)
    encryptedvalue = encryptedvalue.encode('hex')

Java:

public static byte[] encrypt(String value, String rc2Key) throws Exception {

        byte[] valueBytes = Hex.decodeHex(value.toCharArray());
        byte[] rc2KeyBytes = Hex.decodeHex(rc2Key.toCharArray());
        Key k = new SecretKeySpec(rc2KeyBytes, "RC2");
        byte[] iv = {0,0,0,0,0,0,0,0};
        RC2ParameterSpec spec = new RC2ParameterSpec(rc2Key.length() * 4, iv);
        
        Cipher cipher = Cipher.getInstance("RC2/CBC/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, k, spec);
        byte[] encrypted = cipher.doFinal(valueBytes);
        return encrypted;
    }

Why am I getting different encrypted values? What step am I missing. I'm fluent in Python or c# but am a novice with Java so am not sure where I am going wrong...

S3r4ph
  • 1
  • 2
  • 1
    Compare your inputs in hex to make sure they are identical. Do not use any defaults -- they may be different between systems. Explicitly set all defaults in both systems. In some cases one system assumes ASCII and the other utf-8 for example. – rossum Jan 13 '21 at 17:52
  • I'll compare the inputs and make sure they are identical, but I can not change any of the Java code due to it being a legacy system and the developer who wrote it left the company a few years ago. The Java code was used to encrypt about 5000 values in a table, now I am tasked with creating an automated batch encryption/decryption tool for the same system. I've used utf-8 and ascii for my inputs in Python too and no go. – S3r4ph Jan 13 '21 at 19:54
  • Java can use utf-16 internally. Try it both ways, BE and LE to see if they work. – rossum Jan 13 '21 at 20:09
  • utf_16 didn't change the Python result. I am getting the following error message when I try to decrypt the value returned via Python with the Java tool: ```The Decryption failed. This means the encrypted value was not originally encrypted with the RC2 key supplied AND the Encrypted Value and RC2 key are paired.``` – S3r4ph Jan 13 '21 at 21:18
  • Interesting.... The call they gave me to use is a little different than yours: `byte[] result =encrypt("e134db7b54ac00cb4236bb1be093e555613a54a600000000", "4757A2501EF662FD4C62"); System.out.println(Hex.encodeHex(result));` – S3r4ph Jan 14 '21 at 01:25
  • I was just informed this morning too that they are converting the rc2Key to a 40 character hex string **3437353741323530314546363632464434433632** before passing it into the encrypt method. So there is more going on than they first informed me about with the Java tool. I am thinking they must convert it to hex before the tool processes it... Going to run a few tests with this value as the rc2Key as see what turns up between the two different methods. Thanks for the help, at least I know I'm on the right track... – S3r4ph Jan 14 '21 at 18:36

1 Answers1

0

The code is good. I figured out that the values given to me were wrong for testing. I had to send the length of the key before decoding the hex value here: cipher = ARC2.new(key, ARC2.MODE_CBC, iv=iv, effective_keylen=ef_keylen)

I corrected the cipher to: cipher = ARC2.new(b_rc2key, ARC2.MODE_CBC, iv, effective_keylen=len(rc2key)*4)

S3r4ph
  • 1
  • 2