有谁知道JDeveloper/SQL Developer使用什么加密技术来保存凭据?

对我来说,了解这里使用哪种技术来持久化敏感数据会很有趣,因为我需要实现类似的解决方案。下面是一个示例连接配置和生成的导出代码段:

Oracle SQL Developer Connections

<?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>

任何建议将不胜感激。


答案 1

对于好奇的人来说,您实际看到的是与加密密码串联的密钥。例如,我尝试使用以下命令加密密码“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);
}

答案 2

请注意,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" 

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


推荐