3

我目前正在Android上使用AES 256實現對稱en//解密,受此帖的啓發: Java 256bit AES Encryption。 我的實現的目的是我想加密數據庫中的數據。使用一個密鑰和每個消息隨機IV的Android AES基於密碼的加密

對於我用下面的構造函數需要一個char []密碼密鑰生成:因此

public Cryptography(char[] password) throws NoSuchAlgorithmException, 
     InvalidKeySpecException, NoSuchPaddingException { 

    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC"); 
    KeySpec spec = new PBEKeySpec(password, salt, 1024, 256); 
    secretKey = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); 
    cipher = Cipher.getInstance(AES/CBC/PKCS5Padding); 
} 

所以,當我開始我的活動在Android的我初始化我的加密類的新實例,並得到一個生成的密鑰。 salt是一個16字節的固定隨機字節[]。所以這意味着我總是得到同樣的鑰匙。之後的原因。

現在我在一個活動得到了一個對象後,我可以使用下面的加密和解密總是具有相同的密鑰的方法:

public byte[] encrypt(String cleartext) throws InvalidKeyException, 
     IllegalBlockSizeException, BadPaddingException, 
     UnsupportedEncodingException, InvalidParameterSpecException { 

    cipher.init(Cipher.ENCRYPT_MODE, secretKey); 

    byte[] encText = cipher.doFinal(cleartext.getBytes(CHARSET_NAME)); 
    byte[] iv = cipher.getParameters() 
      .getParameterSpec(IvParameterSpec.class).getIV(); 

    byte[] enc = new byte[IV_SIZE + encText.length]; 

    for (int i = 0; i < enc.length; i++) { 
     if (i < IV_SIZE) 
      enc[i] = iv[i]; 
     else if (i < enc.length) 
      enc[i] = encText[i - IV_SIZE]; 
    } 

    return enc; 
} 

public String decrypt(byte[] encryptedText) throws InvalidKeyException, 
     InvalidAlgorithmParameterException, UnsupportedEncodingException, 
     IllegalBlockSizeException, BadPaddingException { 

    byte[] iv = new byte[IV_SIZE]; 
    byte[] dec = new byte[encryptedText.length - IV_SIZE]; 

    for (int i = 0; i < encryptedText.length; i++) { 
     if (i < IV_SIZE) 
      iv[i] = encryptedText[i]; 
     else if (i < encryptedText.length) 
      dec[i - IV_SIZE] = encryptedText[i]; 
    } 

    cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); 

    return new String(cipher.doFinal(dec), CHARSET_NAME); 
} 

正如你所看到的,我救一個全新的IV與密文一起每次我加密一條消息。總結:我在數據庫表中使用了一個加密密鑰,一個隨機鹽和一個新的IV用於每個字段。

首先,我想用新鹽和新IV生成一個新密鑰,每次我加密數據庫表中的一個字段,並將所需的salt和IV與密文一起保存,或者至少對於一個表格行。但是我之所以這樣做是因爲在Android設備上生成密鑰花費了很多時間。我在仿真器上進行了測試,但生成密鑰花了大約兩秒鐘。這就是爲什麼當Activity開始時我只生成了一個鍵。

因此,最後我的問題: 用我的方法,它是足夠安全的只用一個鍵,但新鮮的隨機四的每個消息?目前,我沒有看到通過保持其與性能平衡來使其儘可能安全的另一種方式。

我希望我寫得很清楚,有人可以給我一些建議。

親切的問候

xoidberg

回答

1

我相信這個問題是不相關的,你(xoidberg),但也可能是相關的其他一些人。

從我的理解 - 你使用salt從密碼創建(安全隨機)密鑰。如果每個用戶都有一個隨機的(不同的)鹽 - 這是沒問題的。否則它可能會有問題。

我相信這就是你所做的,所以對我來說似乎沒問題。

我只想提一提通常在保存某些值(通常是密碼)的散列函數時要使用salt。像MD5或SHA這樣的散列函數沒有密鑰,並且您必須爲此添加隨機數。這就是爲什麼你需要鹽,這就是爲什麼在這種情況下,你通常需要對每個值隨機加鹽(如果你只是用相同的鹽保存密碼哈希值,可以檢測最常見的哈希值,並瞭解用戶的密碼最常用的散列是123456)。在你的情況下 - 每個用戶都需要一種獨特的鹽。

關於IV - 你真的需要一個隨機的每一次(所以它沒問題)。