2

i have a legacy oracle functions which use DES3Encrypt and DES3Decrypt function.

I need to write the java equivalent version in order to replace the oracle ones keeping compatibiliy with legacy encryption system.

These are the oracle functions:

//ENCRYPTION
FUNCTION encr(input_string IN VARCHAR2, key_string IN VARCHAR2)
    RETURN VARCHAR2 IS
    encrypted_string := NULL;
    len              := lengthb(input_string);
    --String must be a multiple of 8-byte length.
    rest := len MOD 8;
    IF rest > 0 THEN
        decrypted_string := rpad(input_string, len + 8 - rest, ' ');
    ELSE
        decrypted_string := input_string;
    END IF;

    dbms_obfuscation_toolkit.DES3Encrypt(input_string     => decrypted_string,
                                     key_string       => key_string,
                                     encrypted_string => encrypted_string);

    /* HEX notation to avoid UNICODE chars */
    SELECT RAWTOHEX(encrypted_string) INTO encrypted_string FROM DUAL;

    RETURN encrypted_string;
END;

//DECRYPTION
FUNCTION decr(input_string IN VARCHAR2, key_string IN VARCHAR2)
   RETURN VARCHAR2 IS
   decrypted_string := NULL;
   encrypted_string := input_string;

   /* HEX to ASCII */
   SELECT utl_raw.cast_to_varchar2(encrypted_string)
   INTO encrypted_string
   FROM DUAL;

   dbms_obfuscation_toolkit.DES3Decrypt(input_string     => encrypted_string,
                                     key_string       => key_string,
                                     decrypted_string => decrypted_string);

  RETURN rtrim(decrypted_string);
END;

Considering the Decrypt function, for example i wrote this java code:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


public class DesHelper { 
    private Cipher _dcipher;
    public DesHelper() {
       try {

           byte[] tdesKey = new byte[24];
           System.arraycopy("2557133392096270".getBytes(StandardCharsets.US_ASCII), 0, tdesKey, 0, 16);
           System.arraycopy("2557133392096270".getBytes(StandardCharsets.US_ASCII), 0, tdesKey, 16, 8);

           final SecretKey key = new SecretKeySpec(tdesKey, "DESede");

           _dcipher = Cipher.getInstance("DESede/CBC/NoPadding");
           final IvParameterSpec iv = new IvParameterSpec(new byte[8]);

           _dcipher.init(Cipher.DECRYPT_MODE, key,iv);

      } catch (final Exception e) {
          throw new RuntimeException(e);
      }
  }


  public String decrypt(final String str) {
      try {

          final byte[] dec1 = hexToBytes(str);
          final byte[] decryptedBytes = _dcipher.doFinal(dec1);   
          return new String(decryptedBytes, StandardCharacters.US_ASCII);
      } catch (final Exception e) {
          System.out.println("decrypting string failed: " + str + " (" + e.getMessage() + ")");
          return null;
      }
  }

 private static byte[] hexToBytes(final String hex) {
      final byte[] bytes = new byte[hex.length() / 2];
      for (int i = 0; i < bytes.length; i++) {
          bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
      }
      return bytes;
 }

}

This is the main:

Public class MainClass{

      public static void main (final String[] args){

          String txtToBeDecrypted = "DA67C73756184F20ED92DF1614CB85ED";

         final DesHelper h = new DesHelper();

         String xc = h.decrypt(txtToBeDecrypted);

         System.out.printls(xc);

     }

}

But the printed result is still a mess of characters like these:

lZ5 ????rd
where only "rd" is correct (being the last part of the decrypted word).

the correct decrypted word should be "mypassword"

if the password changes into mypasswordmypass ( encrypted: 5543417F4834268A2799D9289D864BFB ) ... i get: lZ5????rdmypass ---> it seems that the first 64 bits are always wrong.

What's wrong in my code? is it just an encoding matter?

Alex
  • 1,515
  • 2
  • 22
  • 44
  • Well what was the original value? – Kayaman Dec 08 '15 at 19:39
  • You assume that the decryption yields a UTF-8-encoded byte sequence corresponding to the original character sequence. It is not obvious to me that that's consistent with what the presented encryption function will produce. It may depend on the database character set. – John Bollinger Dec 08 '15 at 19:47
  • _dcipher is ...private Cipher _dcipher; – Alex Dec 08 '15 at 19:59
  • the right decrypted string is something like: mux_ipon_tra – Alex Dec 08 '15 at 20:07
  • how can i get the right encoding used by the legacy database? – Alex Dec 08 '15 at 20:10
  • i found that NLS_CHARACTERSET is AL32UTF8 i guess uft-8 is the right encoding... but the result is still not right... – Alex Dec 08 '15 at 20:23

0 Answers0