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?