2016-12-27 5 views
0

나는이 주제에 관해서 거의 모든 주제를 다뤘지만, 여전히 틀린 것은 무엇인지 알아낼 수 없다. 내 안드로이드 애플 리케이션에 3 EditText을 만들었습니다 : EditText 암호화 및 해독을 위해 키/암호를 삽입합니다. EditText2 여기서 암호화 된 텍스트가 표시됩니다. EditText3 여기서 해독 된 텍스트가 표시됩니다.Blowfish가 암호화/해독을위한 안드로이드 스튜디오에

아직 초기 테스트이기 때문에 앱의 변수로 Crypt에 메시지 또는 문자열을 넣었습니다.

문제는 암호화가 복어 알고리즘과 비슷하기 때문에 아무 문제가 없습니다. (2로 끝납니다 == 그래서 나는 제대로 작동한다고 생각합니다). 또한 복호화 전에 문자열을 해독하려고했거나 좋은 결과없이 암호화에서 byte[]을 사용했습니다. 암호 해독은 원본 String 텍스트를 되돌려주지 않고 대신 암호화 된 텍스트보다 큰 것을 제공합니다. 나는 복어의 양식에 대한 선호도가 없기 때문에 Blowfish/CFB/NoPadding으로 시작했습니다.

str_key, str2str3은 현재 공개되어 있습니다. str2EditText2 필드의 텍스트를 설정하고 str3EditText3 필드의 텍스트를 설정합니다. 출력의 예 : 여기

public void encrypt(){ 
    //encrypt 
    EditText mEdit = (EditText)findViewById(R.id.editText); 
    str_key = (String) mEdit.getText().toString(); 

    int iterationCount = 1000; 
    int keyLength = 256; 
    int saltLength = keyLength/8; 

    SecureRandom random = new SecureRandom(); 
    byte[] salt = new byte[saltLength]; 
    random.nextBytes(salt); 
    KeySpec keySpec = new PBEKeySpec(str_key.toCharArray(), salt, 
      iterationCount, keyLength); 
    SecretKeyFactory keyFactory = null; 
    try { 
     keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    byte[] keyBytes = new byte[0]; 
    try { 
     keyBytes = keyFactory.generateSecret(keySpec).getEncoded(); 
    } catch (InvalidKeySpecException e) { 
     e.printStackTrace(); 
    } 
    SecretKey key = new SecretKeySpec(keyBytes, "Blowfish"); 

    Cipher cipher = null; 
    try { 
     cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding"); 
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } 
    if (cipher == null || key == null) { 
     //throw new Exception("Invalid key or cypher"); 
     str2="error"; 
    } 
    else { 
     byte[] iv = new byte[cipher.getBlockSize()]; 
     random.nextBytes(iv); 
     IvParameterSpec ivParams = new IvParameterSpec(iv); 
     try { 
      cipher.init(Cipher.ENCRYPT_MODE, key,ivParams); 
     } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { 
      e.printStackTrace(); 
     } 


     try { 
      raw = cipher.doFinal(message.getBytes("UTF-8")); 
     } catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } 
     str2 = Base64.encodeToString(raw,Base64.DEFAULT); 

    } 


} 

가 해독 기능입니다 : 여기 Example of output generated from the app

코드의

public void decrypt(){ 
      int iterationCount = 1000; 
      int keyLength = 256; 
      int saltLength = keyLength/8; 
      SecureRandom random = new SecureRandom(); 
      byte[] salt = new byte[saltLength]; 
      random.nextBytes(salt); 
      KeySpec keySpec = new PBEKeySpec(str_key.toCharArray(), salt, iterationCount, keyLength); 
      SecretKeyFactory keyFactory = null; 
      try { 
       keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
       } catch (NoSuchAlgorithmException e) { 
       e.printStackTrace(); 
       } 
       byte[] keyBytes = new byte[0]; 
       try { 
       keyBytes = keyFactory.generateSecret(keySpec).getEncoded(); 
       } catch (InvalidKeySpecException e) { 
        e.printStackTrace(); 
       } 
       SecretKey key = new SecretKeySpec(keyBytes, "Blowfish"); 



    Cipher cipher2 = null; 
    try { 
     cipher2 = Cipher.getInstance("Blowfish/CBC/PKCS5Padding"); 
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } 
    iv = new byte[cipher2.getBlockSize()]; 
    random.nextBytes(iv); 
    IvParameterSpec ivSpec = new IvParameterSpec(iv); 
    try { 
     cipher2.init(Cipher.DECRYPT_MODE, key, ivSpec); 
    } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { 
     e.printStackTrace(); 
    } 
    byte[] decryptedBytes = null; 
    byte[] app= Base64.decode(str2,Base64.DEFAULT); 

    try { 
     decryptedBytes = cipher2.doFinal(app); 
    } catch (IllegalBlockSizeException | BadPaddingException e) { 
     e.printStackTrace(); 
    } 


    str3 = Base64.encodeToString(decryptedBytes,Base64.DEFAULT); 
} 

답변

2

당신은 64 기수로 암호화 된 결과를 인코딩하지만 당신은, 당신의 암호를 해독 할 때 해당 base64의 일반 바이트를 가져옵니다. 먼저 base64로 해독하여 암호문의 실제 바이트 배열을 가져온 다음 해독해야합니다.

또한 UTF8 바이트 배열에서 직접 키를 파생시키는 것이 매우 어렵습니다. 대신 KDF를 사용해야합니다. PBKDF2는 여기에서 가장 일반적으로 사용됩니다.

IV 생성 방법 (전혀 생성하지 않음)은 매우 나쁘다. 무작위로 생성되어 암호문 앞에 추가되어야합니다. 비밀로 할 필요는 없으며 예측할 수 없습니다.

마지막으로, HMAC를 전혀 사용하지 않으므로 누구나 암호문을 변경할 수 있으므로 모를 것입니다.

+0

답장을 보내 주셔서 감사합니다. 나는 또한 base64 디코드를 사용하려고 시도했으며 또한 결과없이 해독을 위해 원래의 "사전"인코딩 된 바이트 배열을 사용하려고했습니다. 내가해야 할 일의 예를들 수 있습니까? KDF.PBKDF2로 UTF-8을 변경해야합니까? 나는 IV를 다음과 같이 생성하려고 시도했다. IvParameterSpec ivSpec = new IvParameterSpec (keySpec.getEncoded()); // 해독 기능에서; 하지만 런타임 오류가 발생합니다. 이것에 대한 예를 나에게 줄 수 있니? – Micene

+0

HMAC를 사용하여 암호 텍스트를 변경하지 않으려면 어떻게해야합니까? – Micene

+1

이것은 Google 검색 할 수있는 모든 물건입니다. 코드를 작성하면 아무 것도 배울 수 없습니다! base64를 해독 한 후에도 해보 았으면 간단히 뭔가 잘못되었습니다. 원본 게시물의 코드를 시도한 내용으로 편집 해보십시오. 거기에서 도와 드리겠습니다. –