How to Decrypt SqlDeveloper connections passwords

To recover password we need two files named connections.xml & product-preferences.xml .
Above files can be available in below locations

On Windows :
%APPDATA%\SQL Developer\system*\o.jdeveloper.db.connection*\connections.xml
%APPDATA%\SQL Developer\system*\o.sqldeveloper*\product-preferences.xml

On Linux :
user_home/.sqldeveloper/system/o.sqldeveloper/connections.xml
user_home/.sqldeveloper/system/o.sqldeveloper/product-preferences.xml

Get required data from connections.xml 
You can find encrypted password in connections.xml, which will looks like below tag

<Reference xmlns="" className="oracle.jdeveloper.db.adapter.DatabaseProvider" name="MyDev DB">
<Factory className="oracle.jdevimpl.db.adapter.DatabaseProviderFactory1212"/>
<RefAddresses>
<StringRefAddr addrType="password">
<Contents>vnmPXCpxyhukK4TmQjrMng==</Contents>
</StringRefAddr>
</RefAddresses>
</Reference>
Get System ID from product-preferences.xml
Search for "db.system.id" from “product-preferences.xml” and you can find similar below
<value n="db.system.id" v="e8a85bc1-414c-4f9e-8a48-9ac5a62382e2"/>

 

Java code to Decrypt
Use below code to Decrpt (Reference : https://github.com/maaaaz/sqldeveloperpassworddecryptor)

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;
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];
 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);
 }

// 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 {

byte[] encrypted = argv[0].getBytes();
 byte[] db_system_id = argv[1].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());
 }
 }
}

Save above code as Decrypt_V4.java .

Compile using javac Decrypt_V4.java 

Usage : “java Decryp_V4 encryped_Password sysem_ID_value”

java Decrypt_V4 vnmPXCpxyhukK4TmQjrMng e8a85bc1-414c-4f9e-8a48-9ac5a62382e2
C:\Oracle>java Decrypt_V4 vnmPXCpxyhukK4TmQjrMng e8a85bc1-414c-4f9e-8a48-9ac5a62382e2
tssqafr11g

 

References :-


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);
}
}
}

view raw

gistfile1.java

hosted with ❤ by GitHub

https://github.com/maaaaz/sqldeveloperpassworddecryptor

10 thoughts on “How to Decrypt SqlDeveloper connections passwords

  1. Getting below error
    javax.crypto.BadPaddingException: Given final block not properly padded

    Like

  2. I can not find product-preferences.xml in any places on system (UBUNTU 18.04 – SQL Developer Version 18.1.0.095, Build 095.1630). Any suggestions?

    Like

  3. SECRET=”$(cat $HOME/.sqldeveloper/system*/o.sqldeveloper/product-preferences.xml | grep db.system.id | sed ‘s/.*v=”\([^”]*\).*/\1/’)”
    PASSWORDS=”$(cat $HOME/.sqldeveloper/system*/o.jdeveloper.db.connection/connections.xml | tr -d ‘\n’ | sed ‘s~~\n~g’ | grep password | sed ‘s/.*//’)”

    for x in $PASSWORDS; do java Decrypt_V4 $x $SECRET; done

    Liked by 1 person

    1. Thanks so much, I couldn’t use that sed regexp, but I did find my db_system_id using Cygwin on windows.
      Thanks OP for the code and reference.

      Like

  4. This doesn’t seem to work anymore for SQL Developer 19 (19.2.0.206 in my case) unfortunately, I also get the response “javax.crypto.BadPaddingException: Given final block not properly padded” that was already mentioned above. With version 18 it worked fine.
    Did Oracle change the key or the encryption method maybe?

    Like

Leave a comment