Does anybody know what encrypting technique is JDeveloper/SQL Developer using to persist credentials? Does anybody know what encrypting technique is JDeveloper/SQL Developer using to persist credentials? java java

Does anybody know what encrypting technique is JDeveloper/SQL Developer using to persist credentials?


For the curious, what you're actually seeing is the secret key concatenated with the encrypted password. For example, I tried encrypting the password "SAILBOAT" using:

DatabaseProviderHelper.goingOut("SAILBOAT")

In this particular instance, the result was:

0527C290B40C41D71139B5E7A4446E94D7678359087249A463

The first byte is constant:

05

The next 8 bytes represent the randomly generated secret key (for the DES cipher):

27C290B40C41D711

The remaining bytes are the encrypted password:

39B5E7A4446E94D7678359087249A463

Therefore, to decrypt the password, you simply use this:

public static byte[] decryptPassword(byte[] result) throws GeneralSecurityException {    byte constant = result[0];    if (constant != 5) {        throw new IllegalArgumentException();    }    byte[] secretKey = new byte[8];    System.arraycopy(result, 1, secretKey, 0, 8);    byte[] encryptedPassword = new byte[result.length - 9];    System.arraycopy(result, 9, encryptedPassword, 0, encryptedPassword.length);    byte[] iv = new byte[8];    for (int i = 0; i < iv.length; i++) {        iv[i] = 0;    }    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secretKey, "DES"), new IvParameterSpec(iv));    return cipher.doFinal(encryptedPassword);}


Note that Tim's password hash above is not for "apps_ro" - presumably he cut and pasted from the wrong place... I won't post the real password in case it's something he doesn't want shared!

I had a similar problem, trying to store my db credentials centrally (for non-secure databases!) and then exporting sql developer xml files. I have no idea what the algorithm is - however, you don't really need to know the algorithm, as you can just call the Oracle java API yourself. If you have SQLDeveloper, just grab the right Jar files:

cp /Applications/SQLDeveloper.App/Contents/Resources/sqldeveloper/BC4J/lib/db-ca.jar .cp /Applications/SQLDeveloper.App/Contents/Resources/sqldeveloper/jlib/ojmisc.jar .

Then either load them in your Java app, or use something like JRuby as I do:

$jirb> require 'java'> require 'ojmisc.jar'> require 'db-ca.jar'> Java::oracle.jdevimpl.db.adapter.DatabaseProviderHelper.goingOut("password")     => "059D45F5EB78C99875F6F6E3C3F66F71352B0EB4668D7DEBF8" > Java::oracle.jdevimpl.db.adapter.DatabaseProviderHelper.goingOut("password") => "055CBB58B69B477714239157A1F95FDDD6E5B453BEB69E5D49" > Java::oracle.jdevimpl.db.adapter.DatabaseProviderHelper.comingIn("059D45F5EB78C99875F6F6E3C3F66F71352B0EB4668D7DEBF8") => "password" > Java::oracle.jdevimpl.db.adapter.DatabaseProviderHelper.comingIn("055CBB58B69B477714239157A1F95FDDD6E5B453BEB69E5D49") => "password" 

Note that the algorithm, whatever it is, has a random factor so the same password used twice can produce two different hex strings.


This solution works great for me...Copied from:http://www.mischiefblog.com/?p=912

import javax.crypto.*;import javax.crypto.spec.*;import java.security.*;/** * Decrypt passwords stored in Oracle SQL Developer. This is intended for * password recovery. *  * Passwords are stored in * ~/.sqldeveloper/system2.1.1.64.39/o.jdeveloper.db.connection * .11.1.1.2.36.55.30/connections.xml */public class Decrypt {    public static byte[] decryptPassword(byte[] result)            throws GeneralSecurityException {        byte constant = result[0];        if (constant != (byte) 5) {            throw new IllegalArgumentException();        }        byte[] secretKey = new byte[8];        System.arraycopy(result, 1, secretKey, 0, 8);        byte[] encryptedPassword = new byte[result.length - 9];        System.arraycopy(result, 9, encryptedPassword, 0,                encryptedPassword.length);        byte[] iv = new byte[8];        for (int i = 0; i < iv.length; i++) {            iv[i] = 0;        }        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secretKey, "DES"),                new IvParameterSpec(iv));        return cipher.doFinal(encryptedPassword);    }    public static void main(String[] args) {        if (args.length != 1) {            System.err.println("Usage:  java Decrypt <password>");            System.exit(1);        }        if (args[0].length() % 2 != 0) {            System.err                    .println("Password must consist of hex pairs.  Length is odd (not even).");            System.exit(2);        }        byte[] secret = new byte[args[0].length() / 2];        for (int i = 0; i < args[0].length(); i += 2) {            String pair = args[0].substring(i, i + 2);            secret[i / 2] = (byte) (Integer.parseInt(pair, 16));        }        try {            System.out.println(new String(decryptPassword(secret)));        } catch (GeneralSecurityException e) {            e.printStackTrace();            System.exit(3);        }    }}