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:
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?
Messaggio modificato da 3136775 Added new snippet code for sake of completeness