programing

컨피규레이션파일 비밀번호 암호화

nicescript 2022. 9. 21. 22:24
반응형

컨피규레이션파일 비밀번호 암호화

컨피규레이션파일로부터 서버 정보를 읽어내는 프로그램이 있어, 그 설정으로 패스워드를 암호화하고 싶다고 생각하고 있습니다.이 패스워드는 프로그램으로 읽어내 복호화할 수 있습니다.

요구 사항:

  • 파일에 저장할 일반 텍스트 암호 암호화
  • 프로그램에서 파일에서 읽은 암호화된 암호를 해독합니다.

이 일을 어떻게 해야 할지 조언해 주실 수 있나요?나는 나만의 알고리즘을 쓸까 생각중이었지만, 그것은 매우 불안정할 것 같다.

이를 위한 간단한 방법은 Java에서 암호 기반 암호화를 사용하는 것입니다.이를 통해 암호를 사용하여 텍스트를 암호화 및 암호 해독할 수 있습니다.

으로 「IOS」의 초기화를 합니다.javax.crypto.Cipher '''에 "AES/CBC/PKCS5Padding"도 합니다.javax.crypto.SecretKeyFactory"PBKDF2WithHmacSHA512"알고리즘.

다음은 코드 예시입니다(보안성이 낮은 MD5 기반 모델을 대체하기 위해 업데이트됨).

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class ProtectedConfigFile {

    public static void main(String[] args) throws Exception {
        String password = System.getProperty("password");
        if (password == null) {
            throw new IllegalArgumentException("Run with -Dpassword=<password>");
        }

        // The salt (probably) can be stored along with the encrypted data
        byte[] salt = new String("12345678").getBytes();

        // Decreasing this speeds down startup time and can be useful during testing, but it also makes it easier for brute force attackers
        int iterationCount = 40000;
        // Other values give me java.security.InvalidKeyException: Illegal key size or default parameters
        int keyLength = 128;
        SecretKeySpec key = createSecretKey(password.toCharArray(),
                salt, iterationCount, keyLength);

        String originalPassword = "secret";
        System.out.println("Original password: " + originalPassword);
        String encryptedPassword = encrypt(originalPassword, key);
        System.out.println("Encrypted password: " + encryptedPassword);
        String decryptedPassword = decrypt(encryptedPassword, key);
        System.out.println("Decrypted password: " + decryptedPassword);
    }

    private static SecretKeySpec createSecretKey(char[] password, byte[] salt, int iterationCount, int keyLength) throws NoSuchAlgorithmException, InvalidKeySpecException {
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
        PBEKeySpec keySpec = new PBEKeySpec(password, salt, iterationCount, keyLength);
        SecretKey keyTmp = keyFactory.generateSecret(keySpec);
        return new SecretKeySpec(keyTmp.getEncoded(), "AES");
    }

    private static String encrypt(String property, SecretKeySpec key) throws GeneralSecurityException, UnsupportedEncodingException {
        Cipher pbeCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        pbeCipher.init(Cipher.ENCRYPT_MODE, key);
        AlgorithmParameters parameters = pbeCipher.getParameters();
        IvParameterSpec ivParameterSpec = parameters.getParameterSpec(IvParameterSpec.class);
        byte[] cryptoText = pbeCipher.doFinal(property.getBytes("UTF-8"));
        byte[] iv = ivParameterSpec.getIV();
        return base64Encode(iv) + ":" + base64Encode(cryptoText);
    }

    private static String base64Encode(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }

    private static String decrypt(String string, SecretKeySpec key) throws GeneralSecurityException, IOException {
        String iv = string.split(":")[0];
        String property = string.split(":")[1];
        Cipher pbeCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        pbeCipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(base64Decode(iv)));
        return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8");
    }

    private static byte[] base64Decode(String property) throws IOException {
        return Base64.getDecoder().decode(property);
    }
}

가지 남아 있습니다. 즉, 이 문제가 남아 있습니다.암호를 암호화하기 위해 사용하는 암호를 어디에 저장해야 합니까?소스 파일에 저장하고 난독화할 수 있지만 다시 찾는 것은 어렵지 않습니다.할 때 할 수 (「Java」 「Java」 「Java」 「Java 「Java」 「Java」 「Java」 「Java」 「Java」 「Java」 「Java」 「Java」 「Java」).-DpropertyProtectionPassword=...를 참조해 주세요.

KeyStore를 사용해도 같은 문제가 발생하며 KeyStore도 비밀번호로 보호됩니다.기본적으로 마스터 패스워드는 1개만 있어야 하는데, 이 패스워드는 보호하기가 쉽지 않습니다.

Jasypt는 최소한의 노력으로 기본적인 암호화 기능을 제공하는 라이브러리입니다.

네, 절대 자기 알고리즘은 쓰지 마세요.자바에는 많은 암호화 API가 있습니다.

인스톨 하는 OS 에 키 스토어가 있는 경우는, 그것을 사용해 암호 키를 보존할 수 있습니다.암호 키는, 설정이나 다른 파일의 기밀 데이터의 암호화와 복호화에 필요합니다.

최선의 방법은 (비밀번호를 포함한) 설정 파일에 특정 사용자 계정에서만 액세스할있도록 하는 것이라고 생각합니다.예를 들어 애플리케이션별 사용자가 있을 수 있습니다.appuser신뢰할 수 있는 사람만이 비밀번호를 가지고 있습니다.su를 참조해 주세요).

이렇게 하면 번거로운 암호화 오버헤드가 발생하지 않고 비밀번호도 안전하게 사용할 수 있습니다.

편집: 어플리케이션 설정을 신뢰할 수 있는 환경 이외로 내보내지 않을 것으로 생각됩니다(질문을 받고 있기 때문에 이 방법이 타당하다고는 생각되지 않습니다).

중요한 점은 어플리케이션이 패스워드를 입수할 수 있으면, 박스에 액세스 할 수 있는 해커도 패스워드를 입수할 수 있다는 것입니다.

이를 회피하는 유일한 방법은 응용 프로그램이 표준 입력을 사용하여 콘솔에서 "마스터 비밀번호"를 요청한 후 이를 사용하여 파일에 저장된 비밀번호를 해독하는 것입니다.물론 이로 인해 부팅 시 애플리케이션을 OS와 함께 자동으로 부팅할 수 없습니다.

그러나 이 정도의 번거로움에도 불구하고 해커가 루트 액세스(또는 애플리케이션을 실행하는 사용자로서만 액세스)에 성공했을 경우, 해커는 메모리를 덤프 해 거기서 패스워드를 찾을 수 있습니다.

확실히 해야 할 것은, 회사 전체가 실가동 서버(및 패스워드)에 액세스 할 수 없게 해, 이 박스를 깨는 것이 불가능하도록 하는 것입니다.

마스터 패스워드의 문제를 해결하려면 (가장 좋은 방법은 패스워드를 아무 곳에나 저장하지 않는 것입니다)어플리케이션 스스로 패스워드를 암호화하여 패스워드를 복호화할 수 있도록 해야 합니다.따라서 .config 파일을 사용하는 경우 mySettings.config:

encryptThesKeys=secretKey, anotherSecret

secretKey=unprotectedPassword ThatIput여기서

anotherSecret=anotherPass

someKey=unprotectedSettingIdontCareAbout

그래서 암호화에 언급된 키를 읽습니다.이러한 키를 위에서 Brodwalls의 예를 적용한 후, 어떤 종류의 마커(crypt:라고 합시다)를 사용하여 파일에 다시 씁니다.이러한 출력은 다음과 같습니다.

encryptThesKeys=secretKey, anotherSecret

secretKey=파일:ii4jfj304fj934fouh938

anotherSecret=폴더:jd48jofh48h

someKey=unprotectedSettingIdontCareAbout

원본을 안전한 곳에 보관하세요

ESAPIs Encryption 메서드를 사용해 보십시오.설정도 간단하고, 키도 간단하게 변경할 수 있습니다.

http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/org/owasp/esapi/Encryptor.html

1) 라이브러리 하나만으로 서명 2) 서명 3) 서명 5) 해시 6) 시간 기반 서명 등을 수행할 수 있습니다.

Jetty에서 패스워드(또는 해시)를 컨피규레이션파일에 보존하기 위해서 사용할 수 있는 것을 확인해, OBF 인코딩이 도움이 되는지를 검토해 주세요.그럼 어떻게 하는지 출처에서 확인하세요.

http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html

컨피규레이션파일이 얼마나 안전한지, 애플리케이션의 신뢰성에 따라서는, http://activemq.apache.org/encrypted-passwords.html 가 적절한 솔루션이 될 가능성이 있습니다.

패스워드의 복호화가 그다지 두렵지 않고, 패스워드 키를 보존하기 위해서 콩을 사용해 설정하는 것은 매우 간단합니다.그러나 보안이 더 필요한 경우 암호를 사용하여 환경 변수를 설정하고 실행 후 제거할 수 있습니다.이 때문에, 애플리케이션/서버의 다운에 대해 염려해 주세요.애플리케이션이 자동적으로 재기동하지 않으면 안 됩니다.

Java 8을 사용하는 경우 내부 Base64 인코더와 디코더를 사용하지 않도록 하려면

return new BASE64Encoder().encode(bytes);

와 함께

return Base64.getEncoder().encodeToString(bytes);

그리고.

return new BASE64Decoder().decodeBuffer(property);

와 함께

return Base64.getDecoder().decode(property);

이 솔루션은 암호 해독 방법이 동일한 위치에 저장되므로 데이터를 보호하지 않습니다.깨지기 더 어렵게 만들 뿐이지주로 인쇄를 하지 않고 실수로 모두에게 보여주지 않습니다.

언급URL : https://stackoverflow.com/questions/1132567/encrypt-password-in-configuration-files

반응형