38

因为我需要实施类似的解决方案,所以我很想了解这里使用哪种技术来保存敏感数据。这是一个示例连接配置和生成的导出片段:

Oracle SQL 开发人员连接

<?xml version = '1.0' encoding = 'UTF-8'?>
    <References xmlns="http://xmlns.oracle.com/adf/jndi">
        <Reference name="My Connection" className="oracle.jdeveloper.db.adapter.DatabaseProvider" xmlns="">
        <Factory className="oracle.jdeveloper.db.adapter.DatabaseProviderFactory"/>
        <RefAddresses>
            <StringRefAddr addrType="user">
                <Contents>username</Contents>
            </StringRefAddr>
            <StringRefAddr addrType="password">
                <Contents>054D4844D8549C0DB78EE1A98FE4E085B8A484D20A81F7DCF8</Contents>
            </StringRefAddr>
        <SKIPPED />
        </RefAddresses>
    </Reference>
</References>

任何建议将不胜感激。

4

11 回答 11

47

出于好奇,您实际上看到的是与加密密码连接的密钥。例如,我尝试使用以下方法加密密码“SAILBOAT”:

DatabaseProviderHelper.goingOut("SAILBOAT")

在这种特殊情况下,结果是:

0527C290B40C41D71139B5E7A4446E94D7678359087249A463

第一个字节是常量:

05

接下来的 8 个字节代表随机生成的密钥(对于 DES 密码):

27C290B40C41D711

剩下的字节是加密的密码:

39B5E7A4446E94D7678359087249A463

因此,要解密密码,您只需使用以下命令:

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);
}
于 2010-06-24T12:11:18.567 回答
11

请注意,上面 Tim 的密码散列不适用于“apps_ro” - 大概是他从错误的位置剪切和粘贴...我不会发布真正的密码,以防他不想共享它!

我有一个类似的问题,试图集中存储我的数据库凭据(对于非安全数据库!),然后导出 sql developer xml 文件。我不知道算法是什么 - 但是,您并不需要知道算法,因为您可以自己调用 Oracle java API。如果您有 SQLDeveloper,只需获取正确的 Jar 文件:

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

然后将它们加载到您的 Java 应用程序中,或者像我一样使用 JRuby 之类的东西:

$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" 

请注意,无论算法是什么,都有一个随机因素,因此使用两次的相同密码可以产生两个不同的十六进制字符串。

于 2010-03-04T01:15:24.383 回答
8

这个解决方案对我很有用...复制自: 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);
        }
    }
}
于 2011-01-20T13:44:52.027 回答
7

给定的解决方案太旧了,只适用于 2.x 版,但现在不行。因为 Oracle SQL Developer,在 3.x 和 4.x 版本中改变了加密算法。

版本 3

密码以加密方式存储在这些位置的 connections.xml 文件中:

Windows: C:\Users\<USER>\AppData\Roaming\SQL Developer\system<VERSION>\o.jdeveloper.db.connection.<VERSION>\connections.xml
Linux: ~/.sqldeveloper/system<VERSION>/o.jdeveloper.db.connection.<VERSION>/connections.xml

版本 4

密码以加密方式存储在上述connections.xml 文件中,但加密密钥使用product-preferences.xml 文件中的机器唯一值db.system.id 可在此处访问:

Windows: C:\Users\<USER>\AppData\Roaming\SQL Developer\system<VERSION>\o.sqldeveloper.<VERSION>\product-preferences.xml
Linux: ~/.sqldeveloper/system<VERSION>/o.sqldeveloper.<VERSION>/product-preferences.xml

要解密最新的加密文件,您可以使用SQL Developer 的Show me password extension。或使用SQL Developer 密码解密器解密文件

于 2016-04-21T06:19:48.617 回答
5

与 kornelissietsma 给出的代码相同,但用 java 编写:

import oracle.jdevimpl.db.adapter.DatabaseProviderHelper;

class Decode {
    String pass = ""; 

    public Decode() {
        pass = DatabaseProviderHelper.comingIn("HASH");
        System.out.println(pass);
    }   

    public static void main(String[] args){
        new Decode();
    }   
}

可以执行如下:

# javac -classpath .:/full/path/to/sqldeveloper/BC4J/lib/db-ca.jar:/full/path/to/sqldeveloper/jlib/ojmisc.jar sqldeveloper_hash_decode.java
# java -classpath .:/full/path/to/sqldeveloper/BC4J/lib/db-ca.jar:/full/path/to/sqldeveloper/jlib/ojmisc.jar Decode
于 2010-06-24T07:14:37.273 回答
5

不幸的是,其他答案中描述的方法在 SQL Developer 4.x 中不起作用。有适用于 3.x 和 4.x 版本的扩展,并且非常易于使用:

https://github.com/tomecode/show-me-password-sqldev-jdev

于 2015-03-09T18:23:01.523 回答
4

我不确定这一点,但我一直认为哈希无法解密,只能与另一个哈希相比。MD5 生成一个哈希。SQL Developer中保存的密码需要解密后发送到服务器。所以 dbms_obfuscation_toolkit 包中的 DES3Encrypt 和 DES3Decrypt 过程是一个更好的选择。但是解密应该在连接到数据库之前调用,所以它可能是一个带有 DES 方法的 Java 加密包。

于 2009-06-23T20:29:27.867 回答
2

如果有人感兴趣,这是一个 python 片段。这是上面亚当佩恩特示例的翻译。它使用pyDes

import os
import pyDes

import binascii

if __name__ == '__main__':
    # Encrypt example
    zero = '\0\0\0\0\0\0\0\0'
    key = os.urandom(8)
    plainText = 'open sesame'
    cipher = pyDes.des(key, mode=pyDes.CBC, IV=zero, padmode=pyDes.PAD_PKCS5)

    cipherText = '\5%s%s' % (key, cipher.encrypt(plainText))
    cipherHex = binascii.hexlify(cipherText)

    # This is what SQLDeveloper stores in XML
    print cipherHex

    # Decrypt above
    cipherText = binascii.unhexlify(cipherHex)
    assert cipherHex[0:2] == '05'
    key = cipherText[1:1+8]
    cipher = pyDes.des(key, mode=pyDes.CBC, IV=zero, padmode=pyDes.PAD_PKCS5)
    print cipher.decrypt(cipherText[1+8:])
于 2013-08-02T16:08:25.990 回答
1

我不知道,但如果DBMS_OBFUSCATION_TOOLKIT被这样使用,我不会感到惊讶:

l_hash := dbms_obfuscation_toolkit.md5(input_string=>:username||:password);
于 2009-06-23T19:47:06.767 回答
1

哈希的长度是 50 个十六进制字符,即 200 位,所以它可能是带有盐的密码的哈希,前面带有盐,例如:

salt | hash(salt | password)

在哪里 | 是串联的意思。

不过只是猜测。我的猜测是 40 位盐和 SHA-1 哈希,因为 SHA-1 产生 160 位哈希。

提供一些输入/输出测试数据来检查会很有帮助!

于 2009-06-23T19:53:27.657 回答
-3

仅供参考,密码“apps_ro”加密为:

     <StringRefAddr addrType="password">
        <Contents>051DC8A88C574538CC4AEE32D326E9480659C06CEC271EA6D7</Contents>
     </StringRefAddr>
于 2010-02-25T16:53:38.100 回答