programing

JDeveloper/SQL Developer가 자격 증명을 유지하기 위해 사용하는 암호화 기술을 아는 사람이 있습니까?

cafebook 2023. 3. 4. 15:09
반응형

JDeveloper/SQL Developer가 자격 증명을 유지하기 위해 사용하는 암호화 기술을 아는 사람이 있습니까?

유사한 솔루션을 구현해야 하므로 여기서 어떤 기술을 사용하여 합리적인 데이터를 유지하는지 이해하는 것이 훨씬 더 흥미롭습니다.다음으로 접속 설정 예와 내보내기된 스니펫을 나타냅니다.

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>

어떤 조언이라도 해주시면 감사하겠습니다.

궁금하신 분들을 위해 실제로 보고 계신 것은 암호화된 비밀번호와 연결된 비밀키입니다.예를 들어, 다음과 같은 방법으로 "SAILBOAT" 비밀번호를 암호화하려고 했습니다.

DatabaseProviderHelper.goingOut("SAILBOAT")

이 특정 인스턴스의 결과는 다음과 같습니다.

0527C290B40C41D71139B5E7A446E94D7678359087249A463

첫 번째 바이트는 상수입니다.

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

위의 Tim의 패스워드 해시는 "apps_ro"가 아닙니다.아마 잘못된 장소에서 잘라내어 붙여넣은 것 같습니다.그가 공유하길 원하지 않는 경우에 대비하여 진짜 비밀번호는 게시하지 않을 거야!

DB 자격 증명을 중앙(비보안 데이터베이스용!)에 저장하려다가 SQL 개발자 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" 

알고리즘에는 임의의 계수가 있기 때문에 같은 패스워드를 2회 사용해도2개의 다른 16진수 문자열을 생성할 수 있습니다.

이 솔루션은 나에게 매우 효과적입니다.복사원: 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);
        }
    }
}

Oracle SQL Developer가 버전 3.x 및 4.x에서 암호화 알고리즘을 변경했기 때문에 지정된 솔루션은 너무 오래되어 버전 2.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 파일에 암호화되어 저장되지만 암호화 키는 다음 URL에서 액세스할 수 있는 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 확장자를 사용하여 암호화된 최신 파일을 해독할 수 있습니다.또는 SQL Developer password decryptor를 사용하여 파일 복호화

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

유감스럽게도 다른 답변에서 설명된 메서드는 SQL Developer 4.x에서는 작동하지 않습니다.3.x 버전과 4.x 버전 모두에서 사용할 수 있는 확장 기능이 있으며 매우 사용하기 쉽습니다.

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

나는 이것에 대해 확신할 수 없지만 항상 해시는 해독될 수 없다고 생각했다. 단지 다른 해시와 비교했을 뿐이다.MD5는 해시를 생성합니다.SQL Developer에 저장된 암호를 해독하여 서버로 전송해야 합니다.따라서 dbms_obenciphation_toolkit 패키지의 DES3 Encrypt 및 DES3 Decrypt 프로시저가 더 적합합니다.단, 데이터베이스에 연결하기 전에 복호화를 호출해야 합니다.따라서 DES 메서드를 사용하는 Java 암호화 패키지일 수 있습니다.

여기 관심있는 사람이 있다면 비단뱀 조각이 있습니다.위의 Adam Paynter의 예를 번역한 것입니다.pyD를 사용합니다.

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:])

모르겠습니다만, DBMS_OBPHICATION_TOOLKIT가 다음과 같이 사용되고 있다고 해도 놀라지 않을 것입니다.

l_hash := dbms_obfuscation_toolkit.md5(input_string=>:username||:password);

해시의 길이는 16진수 50자(200비트)이므로 다음과 같이 salt가 부가된 salt가 있는 패스워드의 해시일 수 있습니다.

salt | hash(salt | password)

여기서 |는 연결을 의미합니다.

그냥 추측일 뿐이야SHA-1은 160비트 해시를 생성하기 때문에 40비트 소금과 SHA-1 해시가 될 것입니다.

대조할 입출력 테스트 데이터를 제공하는 것이 도움이 됩니다!

참고로 비밀번호 'apps_ro'는 다음과 같이 암호화됩니다.

     <StringRefAddr addrType="password">
        <Contents>051DC8A88C574538CC4AEE32D326E9480659C06CEC271EA6D7</Contents>
     </StringRefAddr>

언급URL : https://stackoverflow.com/questions/1032721/does-anybody-know-what-encrypting-technique-is-jdeveloper-sql-developer-using-to

반응형