Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Oracle encryption -> Java decryption 1

Status
Not open for further replies.

userMikeD

Programmer
Nov 5, 2008
28
0
0
US
Hi,

I'm writing a java app that needs to retrieve encrypted values in a table, and decrypt them on the java side. The oracle side encryption and decryption works fine, but I'm getting null on the java side.

Here's Oracle code that works to decrypt the value:
Code:
   SELECT CONVERT(key_1, 'WE8ISO8859P1', 'UTF8'),
          CONVERT(key_2, 'WE8ISO8859P1', 'UTF8')
     INTO v_key1, v_key2
     FROM encrypted_keys;

   v_result := dbms_obfuscation_toolkit.desdecrypt(input_string => v_key2,
                                                   key_string   => v_key1);

Hre's my java code to read these values from the table and decrypt
Code:
Connection conn = getConnection();
PreparedStatement ps = null;
String key1, key2, decrypted;
key1 = key2 = decrypted = null;

try {
	ps = conn.prepareStatement("SELECT CONVERT(key_1, 'WE8ISO8859P1', 'UTF8'), CONVERT(key_2, 'WE8ISO8859P1', 'UTF8') from encrypted_keys");
	ResultSet rs = ps.executeQuery();
	rs.next();
	key1 = rs.getString(1);
	key2 = rs.getString(2);
	rs.close();
	ps.close();
	conn.close();

	DesEncrypter encrypter = new DesEncrypter(key1);
	decrypted = encrypter.decrypt(key2);

} catch (SQLException e) {}

And here's the DesEncrypter class I found:
Code:
import java.io.UnsupportedEncodingException;
import java.security.spec.KeySpec;
import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;

public class DesEncrypter {
    Cipher ecipher;
    Cipher dcipher;

    DesEncrypter(String passPhrase) {
        try {
            KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray());
            SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);
            ecipher = Cipher.getInstance(key.getAlgorithm());
            dcipher = Cipher.getInstance(key.getAlgorithm());
            ecipher.init(Cipher.ENCRYPT_MODE, key);
            dcipher.init(Cipher.DECRYPT_MODE, key);
        } catch (javax.crypto.NoSuchPaddingException e) {
        } catch (java.security.spec.InvalidKeySpecException e) {
        } catch (java.security.NoSuchAlgorithmException e) {
        } catch (java.security.InvalidKeyException e) {
        }
    }
    
    public String encrypt(String str) {
        try {
            byte[] utf8 = str.getBytes("UTF8");
            byte[] enc = ecipher.doFinal(utf8);
            return new sun.misc.BASE64Encoder().encode(enc);
        } catch (javax.crypto.BadPaddingException e) { return e.toString();
        } catch (IllegalBlockSizeException e) { return e.toString();
        } catch (UnsupportedEncodingException e) { return e.toString();
        } catch (java.io.IOException e) { return e.toString();
        }
    }
    
    public String decrypt(String str) {
        try {
            byte[] dec = str.getBytes();
            byte[] utf8 = dcipher.doFinal(dec);
            return new String(utf8, "UTF8");
        } catch (javax.crypto.BadPaddingException e) { return e.toString();
        } catch (IllegalBlockSizeException e) { return e.toString();
        } catch (UnsupportedEncodingException e) { return e.toString();
        } catch (java.io.IOException e) { return e.toString();
        }
    }

}

The values from the table are coming across to java correctly. I just can't get the decryption to work. Any have a suggestion of what I should try?

Thanks in advance!
 
So you first invoke the CONVERT and then the decrypt. What does CONVERT do exactly?

Cheers,
Dian
 
Hi, thanks for the replies. The convert is to safely handle the different character sets from the source table on one DB to the snapshot on the other DB. I believe this part is working properly.

I found that the DES encryption in Oracle and the DES encryption in Java are producing different results on the same inputs for strings over 8 bits. Allow me to illustrate.

Oracle Code:
Code:
DECLARE
   v_enc_hex VARCHAR2(100);
BEGIN
   v_enc_hex := dbms_obfuscation_toolkit.DESEncrypt(input_string=>'12345678', key_string=>'password');
   SELECT LOWER(RAWTOHEX(v_enc_hex))
     INTO v_enc_hex
     FROM DUAL;
   dbms_output.put_line('v_enc_hex: '||v_enc_hex);
END;
returns f7a2744e551b356b

Java code
Code:
	DesEncrypter encrypter = new DesEncrypter("password");
	encKey = encrypter.encrypt("12345678");
returns f7a2744e551b356b

So they match on 8 bit strings, but on 16 bit strings, I get different results.

Oracle code:
Code:
DECLARE
   v_enc_hex VARCHAR2(100);
BEGIN
   v_enc_hex := dbms_obfuscation_toolkit.DESEncrypt(input_string=>'1234567890123456', key_string=>'password');
   SELECT LOWER(RAWTOHEX(v_enc_hex))
     INTO v_enc_hex
     FROM DUAL;
   dbms_output.put_line('v_enc_hex: '||v_enc_hex);
END;
returns f7a2744e551b356bd79c18f21b1f3fad

Java code:
Code:
	 DesEncrypter encrypter = new DesEncrypter("password");
	encKey = encrypter.encrypt("1234567890123456");
returns f7a2744e551b356b3b9c0ac7464699d2

So that's:
Oracle: f7a2744e551b356b d79c18f21b1f3fad
Java : f7a2744e551b356b 3b9c0ac7464699d2

Any idea why they begin to differ exactly half way through the results? I think this is the same reason the decryption doesn't work. Thanks again for the help!
 
I found a solution. I had the wrong encryption mode, and I needed to initialize it with a vector containing 0s. Here's what finally worked:

Code:
        	KeySpec keySpec = new DESKeySpec(passPhrase.getBytes());
            SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);
            ecipher = Cipher.getInstance("DES/CBC/NoPadding");
            dcipher = Cipher.getInstance("DES/CBC/NoPadding");
            IvParameterSpec ips = new IvParameterSpec(new byte[] {0,0,0,0,0,0,0,0});
            ecipher.init(Cipher.ENCRYPT_MODE, key, ips);
            dcipher.init(Cipher.DECRYPT_MODE, key, ips);

With that, the encryption/decryption works between Oracle and Java.

Thanks for looking. I hope this helps someone else.
 
Congratulations. The best thing is that you can solve the problem without help.

new byte[] {0,0,0,0,0,0,0,0} is the initialization of a byte array.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top