2017-06-23 26 views
0

我需要在項目中使用JNCryptor庫,所以我首先嚐試獲得一個非常簡單的加密/解密示例。我的程序只是加密一個短的字符串,然後解密並顯示結果。問題是我沒有得到原始文本。下面是輸出當它運行:JNCryptor:爲什麼我的解密數據調用不會產生正確的結果?

C:\Java\JNCryptor_Test>java JNCryptorTest 
Encrypted text: [[email protected] 
Encrypted text back to plain text: [[email protected] 

誰能告訴我什麼,我做錯了什麼?

這裏是我的課JNCryptorTest的源代碼:

import org.cryptonode.jncryptor.JNCryptor; 
import org.cryptonode.jncryptor.AES256JNCryptor; 
import org.cryptonode.jncryptor.CryptorException; 


public class JNCryptorTest 
{ 
    private static String plaintext = "Hello, World!"; 
    private static String password = "secretsquirrel"; 

    public static void main(String[] args) 
    { 
     AllowAes256BitKeys.fixKeyLength(); 
     byte[] encrypted = encrypt(plaintext); 
     System.out.println("Encrypted text: " + encrypted.toString()); 
     String decrypted = decrypt(encrypted); 
     System.out.println("Encrypted text back to plain text: " + decrypted); 
    } 

    private static byte[] encrypt(String s) 
    { 
     JNCryptor cryptor = new AES256JNCryptor(); 
     try 
     { 
      return cryptor.encryptData(s.getBytes(), password.toCharArray()); 
     } 
     catch (CryptorException e) 
     { 
      // Something went wrong 
      e.printStackTrace(); 
      return null; 
     } 
    } 


    private static String decrypt(byte[] msg) 
    { 
     JNCryptor cryptor = new AES256JNCryptor(); 
     try 
     { 
      return (cryptor.decryptData(msg, 
             password.toCharArray())).toString(); 
     } 
     catch (CryptorException e) 
     { 
      // Something went wrong 
      e.printStackTrace(); 
      return null; 
     } 
    } 
} 

此外,我不得不創建一個類AllowAes256BitKeys允許256位密鑰。建議在JVM中安裝「無限強度管轄區文件」,但這在我們的網站中是不可接受的,所以我找到了一種不這樣做的方法(請參閱Java Security: Illegal key size or default parameters?)。

這裏是我的課AllowAes256BitKeys的源代碼:

import javax.crypto.Cipher; 
import java.lang.reflect.Constructor; 
import java.lang.reflect.Field; 
import java.lang.reflect.Modifier; 
import java.util.Map; 


public class AllowAes256BitKeys 
{ 
    // From https://stackoverflow.com/questions/6481627/java-security-illegal-key-size-or-default-parameters 

    public static void fixKeyLength() 
    { 
     String errorString = 
      "Unable to manually override key-length permissions."; 
     int newMaxKeyLength; 
     try 
     { 
      if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) 
      { 
       Class<?> c = 
        Class.forName("javax.crypto.CryptoAllPermissionCollection"); 
       Constructor con = c.getDeclaredConstructor(); 
       con.setAccessible(true); 
       Object allPermissionCollection = con.newInstance(); 
       Field f = c.getDeclaredField("all_allowed"); 
       f.setAccessible(true); 
       f.setBoolean(allPermissionCollection, true); 

       c = Class.forName("javax.crypto.CryptoPermissions"); 
       con = c.getDeclaredConstructor(); 
       con.setAccessible(true); 
       Object allPermissions = con.newInstance(); 
       f = c.getDeclaredField("perms"); 
       f.setAccessible(true); 
       // Warnings suppressed because CryptoPermissions uses a raw Map 
       @SuppressWarnings({"unchecked"}) 
       Object junk = // Only need this so we can use @SuppressWarnings 
        ((Map) f.get(allPermissions)).put("*", allPermissionCollection); 
//    ((Map) f.get(allPermissions)).put("*", allPermissionCollection); 

       c = Class.forName("javax.crypto.JceSecurityManager"); 
       f = c.getDeclaredField("defaultPolicy"); 
       f.setAccessible(true); 
       Field mf = Field.class.getDeclaredField("modifiers"); 
       mf.setAccessible(true); 
       mf.setInt(f, f.getModifiers() & ~Modifier.FINAL); 
       f.set(null, allPermissions); 

       newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES"); 
      } 
     } 
     catch (Exception e) 
     { 
      throw new RuntimeException(errorString, e); 
     } 
    if (newMaxKeyLength < 256) 
     throw new RuntimeException(errorString); // hack failed 
    } 
} 

感謝

+0

您是否嘗試過不使用'AllowAes256BitKeys',只是使用默認的JNCryptor來確定問題? – zaph

+0

是的,但我無法執行此操作,因爲它無效的鍵異常失敗。解決方案是將無限強度管轄區文件安裝到JVM中。但是,正如我所說的,我們不允許在我們的網站上「破解」JVM。 –

+0

1.雖然我理解使用不比128位密鑰更安全的256位密鑰的願望,但兩者都不能被強制使用。 256位的兩個合理原因是128-qubit量子計算機可以以可承受的成本創建或僅僅因爲可以創建的可能性。 2.任何攻擊都將違背密碼而不是密鑰或應用[Rubber-hose密碼分析](https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis)。 – zaph

回答

0

但是,我能夠從一個更有經驗的Java開發者一些幫助來解決這個自己。事實證明,JNCryptor沒有問題;問題是我正確地將解密結果(一個字節數組)轉換爲一個字符串。 toString方法不是正確的方法;你必須創建一個新的String對象並將字節數組傳遞給它的構造函數。

所以我在我的解密方法改變了這一行

return (cryptor.decryptData(msg, password.toCharArray())).toString(); 

這個

return (new String(cryptor.decryptData(msg, password.toCharArray()))); 

,然後我得到了正確的結果:

Encrypted text: [[email protected] 
Encrypted text back to plain text: Hello, World! 

因此,實際上,JNCryptor是工作正確的整個時間 - 這是我的代碼顯示的結果是問題。

相關問題