Java 有人知道JDeveloper/sqldeveloper使用什么加密技术来保存凭据吗?
我非常有兴趣了解这里使用哪种技术来持久化敏感数据,因为我需要实现类似的解决方案。以下是连接配置示例和导出的代码段:Java 有人知道JDeveloper/sqldeveloper使用什么加密技术来保存凭据吗?,java,oracle,oracle-sqldeveloper,jdeveloper,Java,Oracle,Oracle Sqldeveloper,Jdeveloper,我非常有兴趣了解这里使用哪种技术来持久化敏感数据,因为我需要实现类似的解决方案。以下是连接配置示例和导出的代码段: 用户名 054D4844D8549C0DB78EE1A98FE4E085B8A484D20A81F7DCF8 如果您有任何建议,我将不胜感激。我不知道,但如果它被用于类似这样的用途,我也不会感到惊讶: l_hash := dbms_obfuscation_toolkit.md5(input_string=>:username||:password); 散列的长度为5
用户名
054D4844D8549C0DB78EE1A98FE4E085B8A484D20A81F7DCF8
如果您有任何建议,我将不胜感激。我不知道,但如果它被用于类似这样的用途,我也不会感到惊讶:
l_hash := dbms_obfuscation_toolkit.md5(input_string=>:username||:password);
散列的长度为50个十六进制字符,即200位,因此可能是密码的散列加上一个salt,前面加上salt,如:
salt | hash(salt | password)
其中|表示串联
只是猜测而已。我猜是40位salt和SHA-1散列,因为SHA-1产生160位散列
提供一些输入/输出测试数据以进行检查将很有帮助 我对此不确定,但我一直认为哈希不能被解密,只能与另一个哈希进行比较。MD5生成一个散列。SQL Developer中保存的密码需要解密并发送到服务器。因此,dbms_模糊处理_工具包包中的DES3Encrypt和DES3Decrypt过程是一个更好的选择。但是解密应该在连接到数据库之前调用,所以它可能是一个带有DES方法的Java加密包 FYI密码“apps_ro”加密为:
<StringRefAddr addrType="password">
<Contents>051DC8A88C574538CC4AEE32D326E9480659C06CEC271EA6D7</Contents>
</StringRefAddr>
051DC8A88C574538CC4AEE32D326E9480659C06CEC271EA6D7
请注意,Tim上面的密码散列不是用于“应用程序”—可能是他从错误的位置剪切粘贴的。。。我不会发布真正的密码,以防他不想分享
我也遇到了类似的问题,试图集中存储我的db凭据(对于不安全的数据库!),然后导出SQLDeveloperXML文件。我不知道该算法是什么-但是,您不需要真正了解该算法,因为您可以自己调用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"
请注意,无论算法是什么,它都有一个随机因子,因此使用两次相同的密码可以生成两个不同的十六进制字符串。与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
出于好奇,您实际看到的是与加密密码连接在一起的密钥。例如,我尝试使用以下方法加密密码“SAILBOAT”: 在这一特殊情况下,结果是: 0527C290B40C41D71139B5E7A4446E94D7678359087249A463 0527C290B40C41D71139B5E7A4446E94D7678359087249A463 第一个字节是常量: 05 05 接下来的8个字节表示随机生成的密钥(对于DES密码): 27C290B40C41D711 其余字节为加密密码: 39B5E7A4446E94D7678359087249A463 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);
}
公共静态字节[]解密密码(字节[]结果)引发GeneralSecurityException{
字节常数=结果[0];
如果(常数!=5){
抛出新的IllegalArgumentException();
}
字节[]secretKey=新字节[8];
数组复制(结果,1,secretKey,0,8);
byte[]encryptedPassword=新字节[result.length-9];
System.arraycopy(结果,9,encryptedPassword,0,encryptedPassword.length);
字节[]iv=新字节[8];
for(int i=0;i
这个解决方案对我来说非常有效。。。
抄袭自:
import javax.crypto.*;
导入javax.crypto.spec.*;
导入java.security.*;
/**
*解密存储在Oracle SQL Developer中的密码。这是为了
*密码恢复。
*
*密码存储在
*~/.sqldeveloper/system2.1.1.64.39/o.jdeveloper.db.connection
*.11.1.1.2.36.55.30/connections.xml
*/
公共类解密{
公共静态字节[]解密密码(字节[]结果)
抛出一般安全性异常{
字节常数=结果[0];
如果(常数!=(字节)5){
抛出新的IllegalArgumentException();
}
字节[]secretKey=新字节[8];
数组复制(结果,1,secretKey,0,8);
byte[]encryptedPassword=新字节[result.length-9];
System.arraycopy(结果,9,加密密码,0,
encryptedPassword.length);
字节[]iv=新字节[8];
for(int i=0;i
如果有人感兴趣,这里有一个python代码片段。
这是一个tr
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);
}
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);
}
}
}
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:])
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
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