2017-04-16 1 views
0

내 안드로이드 응용 프로그램에서 해독 할 수있는 기능으로 한 줄의 텍스트를 암호화하고 싶습니다.암호 "PBEWithMD5AndDES"는 "안정적입니까?"

나는 javax.crypto과 관련한 경험이 없지만이 답변은 Encrypt Password in Configuration Files?이며 비슷한 것을 구현했습니다.

코드 :

public String encrypt(String property) throws GeneralSecurityException, UnsupportedEncodingException { 
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); 
    SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD)); 
    Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); 
    pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, ITERATIONS)); 
    return Base64.encodeToString(pbeCipher.doFinal(property.getBytes("UTF-8")), Base64.DEFAULT); 
} 

public String decrypt(String property) throws GeneralSecurityException, IOException { 
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); 
    SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD)); 
    Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); 
    pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, ITERATIONS)); 
    return new String(pbeCipher.doFinal(Base64.decode(property, Base64.DEFAULT)), "UTF-8"); 
} 

나는 그것을 테스트하고 그것을 잘 작동합니다. 하지만 나를 괴롭히는 한 가지가 있습니다.이 메서드는 GeneralSecurityException, UnsupportedEncodingExceptionIOException을 던질 수 있습니다.

질문 : 텍스트가 성공적으로 암호화되어 있지만, 일부 상황 (즉, 같은 새로운 안드로이드 새로운 VM과 버전 또는 무언가) 후 decrypt 방법은 GeneralSecurityException 또는 IOException가 발생하고 응용 프로그램이 있음을 해독 할 수 없습니다 경우가있을 수 본문?

+0

은 물론 ... 그것을 가져 와서 그것을 사용할 수 있습니다. 요즘에는 DES와 MD5를 사용해서는 안되는 것을 고려하면 이런 일이 발생할 수 있습니다. 불행히도,이 답변은 실제로 답할 수 없습니다. PBEWithMD5AndDES를 유지하기 위해 Google에서 모든 공급 업체에 대한 요구 사항이 있다고 생각하지 않기 때문입니다. –

+0

어떻게 미래에 어떤 벤더가 무엇을 할 것이라고 확신 할 수 있습니까? –

+0

@ArtjomB. 아하, 알 겠어. 그리고 내가 알고 있듯이, 모든 알고리즘이 미래에 제거 될 수 있기 때문에 암호를 전혀 사용하지 않는 것이 안전하지 않은가? –

답변

2

예외 사항은 올바른 입력시 갑자기 발생하지 않아야합니다. NoSuchAlgorithmException - 알고리즘이 더 이상 지원되지 않으면 GeneralSecurityException의 하위 클래스가 throw되어야합니다.

임의의 API 또는이 경우 암호화 서비스 -은 취소 할 수 있습니다. 그러나 이것은 모든 함수에 적용되므로이 경우 솔루션 공간이 비어 있습니다. 이 경우 최소한 알고리즘은 잘 정의되어 있으므로 오픈 소스 또는 그와 비슷한 코드를 언제든지 다시 가져올 수 있습니다. 물론 오래된 알고리즘은 더 이상 사용해서는 안되기 때문에 철회 될 수 있지만, 일반적으로 자바와 안드로이드는 더 이상 사용되지 않는 함수를 제거하는 대신 하위 호환성을 유지합니다.


예, 알고리즘은 안정하지만 난 당신이 더 나은 이해를 가지고 단어 안정에서 "B"를 제거해야 할 것 같아요.

DES는 보안에 민감한 물질에 대해서는 더 이상 사용하지 마십시오. 오직 3 키 DES EDE 은 여전히 ​​보안에 가까운 것을 제공하기 위해을 사용할 수 있습니다.

PBK 알고리즘에 사용되는 PBKDF1과 마찬가지로, 확장은 다소 적습니다.

GCM 모드에서 AES와 같은 다른 암호를 사용하거나 PBKDF2와 같은 최신 암호 해시 또는 Argon2와 같은 암호를 사용해야합니다.

귀하의 SALT 상수 - 모든 대문자 이름에서 상수라고 가정합니다. 즉석에서 생성되어야합니다. 일정한 소금을 사용하는 것은 목적을 이깁니다.


하지만 기본적으로 암호를 사용하기 전에 일정 수준의 암호화를 이해해야합니다. 복사/붙여 넣기 보안이 존재하지 않기 때문에 다른 사람과 상담해야합니다.

+0

알았습니다. 필자는 이전에 암호로 작업하지는 않았지만 응용 프로그램에서 SharedPreferences를 추출 할 수 있지만 Base64보다 어려운 것을 암호화 할 수없는 대부분의 "해커"를 걸러 내기 위해 기본 암호화를 추가하려고했습니다. –

+0

글쎄, DES는 64보다 약간 나아졌지만 (전혀 키가 없다) PKCS # 5를 읽은 다음 PBKDF2와 AES를 구현하는 방법을 찾으십시오. Base64는 암호화 스키마가 아닌 * 인코딩 스키마입니다. –

0

DES (CBC) 작동 모드를 사용하기 때문에 쉽게 해독 할 수 있습니다. DES의 유효 키 크기는 56 비트뿐입니다. 따라서 키와는 (PBKDF1) 키 유도에 관계없이 무차별 적으로 강제 될 수 있습니다.

MD5는 PBKDF1 내에서 사용되는 경우 문제가되지 않지만 패스워드에 충분한 엔트로피가 포함되어 있다면 문제가되지 않습니다.

가능하면 PBKDF2 및 AES를 사용하여 PBE (Password-Based Encryption)로 업그레이드해야합니다. PBE는 일반적으로 CBC 모드 암호화를 사용하므로 전송 프로토콜에는 적합하지 않습니다.

그것은 완벽한 작업, 당신은 그냥/안드로이드 공급 업체는 미래의 어떤 시점에서 사용해 PBEWithMD5AndDES를 제거 할 수도

package com.example.siman.friend_pro; 

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 
import java.security.spec.AlgorithmParameterSpec; 
import java.security.spec.InvalidKeySpecException; 
import java.security.spec.KeySpec; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.PBEKeySpec; 
import javax.crypto.spec.PBEParameterSpec; 

import static javax.crypto.Cipher.DECRYPT_MODE; 
import static javax.crypto.Cipher.ENCRYPT_MODE; 
import static javax.crypto.Cipher.getInstance; 

public class Encryptor4j 
{ 
    private static byte[] salt = { 
      (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32, 
      (byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03 
    }; 
    private static Cipher ecipher; 
    private static Cipher dcipher; 
    private static String Property = "youkey"; 
    private static int iterationCount = 19; 

    public static String encrypt(String Text) 
    { 
     String returnvalue=null; 
     try { 
      returnvalue = Encryptor4j.form1(Text); 
     } 
     catch (NoSuchAlgorithmException | InvalidKeySpecException | 
       NoSuchPaddingException | InvalidKeyException | 
       InvalidAlgorithmParameterException | IllegalBlockSizeException | 
       BadPaddingException | IOException e) { 
      e.printStackTrace(); 
     } 
     return returnvalue; 
    } 
    public static String decrypt(String Text) 
    { 
     String returnvalue=null; 
     try { 
      returnvalue = Encryptor4j.form2(Text); 
     } 
     catch (NoSuchAlgorithmException | InvalidKeySpecException | 
       NoSuchPaddingException | InvalidKeyException | 
       InvalidAlgorithmParameterException | IllegalBlockSizeException | 
       BadPaddingException | IOException e) { 
      e.printStackTrace(); 
     } 
     return returnvalue; 
    } 


    private static String form1(String Text) 
      throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException 
    { 
     //Key generation for enc and desc 
     KeySpec keySpec = new PBEKeySpec(Property.toCharArray(), salt, iterationCount); 
     SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec); 
     // Prepare the parameter to the ciphers 
     AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount); 

     //Enc process 
     ecipher = getInstance(key.getAlgorithm()); 
     ecipher.init(ENCRYPT_MODE, key, paramSpec); 
     String charSet = "UTF-8"; 
     byte[] in = Text.getBytes(charSet); 
     byte[] out = ecipher.doFinal(in); 
     String encStr = new String(android.util.Base64.encode(out,0)); 
     //String encStr = new String(Base64.getEncoder().encode(out)); 
     return encStr; 
    } 

    private static String form2(String Text) 
      throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, IOException 
    { 
     //Key generation for enc and desc 
     KeySpec keySpec = new PBEKeySpec(Property.toCharArray(), salt, iterationCount); 
     SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec); 
     // Prepare the parameter to the ciphers 
     AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount); 
     //Decryption process; same key will be used for decr 
     dcipher = getInstance(key.getAlgorithm()); 
     dcipher.init(DECRYPT_MODE, key, paramSpec); 
     //byte[] enc = Base64.getDecoder().decode(encryptedText); 
     byte[] enc = android.util.Base64.decode(Text.getBytes(),0); 
     byte[] utf8 = dcipher.doFinal(enc); 
     String charSet = "UTF-8"; 
     String plainStr = new String(utf8, charSet); 
     return plainStr; 
    } 
}