2016-04-24 39 views
0

我試圖讓密鑰庫幫助我生成AES加密密鑰,並使用它來加密我放入的純文本。所以,這裏是我的碼。我只在另一個activity的onCreate()方法中調用了createKey()方法一次,然後用相同的keyAlias和相同的明文多次調用printCipherText()方法。奇怪的是:每次我調用printCipherText()方法時,我都會得到不同的結果。我使用了相同的密鑰別名和相同的明文,但爲什麼每次都得到不同的密文?Android AES(帶密鑰庫)使用相同的純文本產生不同的密文

public class KeyCreatorClass { 

    KeyStore keyStore; 
    KeyGenerator keyGenerator; 
    Cipher cipher; 

    public void createKey(String keyAlias) { //I call this method only once in the onCreate() method of another activity, with keyAlias "A" 
     try { 
      keyStore = KeyStore.getInstance("AndroidKeyStore"); 
      keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); 
      cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); 
      keyStore.load(null); 
      keyGenerator.init(
        new KeyGenParameterSpec.Builder(keyAlias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 
         .setBlockModes(KeyProperties.BLOCK_MODE_CBC) 
         .setUserAuthenticationRequired(false) 
         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) 
         .setRandomizedEncryptionRequired(false) 
         .build()); 
      keyGenerator.generateKey(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public String printCipherText(String keyAlias, String plainText){ //I call this method many times with the same keyAlias "A" and same plaintext in the same activity 
     try { 
      keyStore.load(null); 
      SecretKey key = (SecretKey) keyStore.getKey(keyAlias, null); 
      cipher.init(Cipher.ENCRYPT_MODE, key); 
      return byteToHex(cipher.doFinal(plainText.getBytes())); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
     return "BUG"; 
    } 

    private String byteToHex(byte[] byteArray){ 
     StringBuilder buf = new StringBuilder(); 
     for (byte b : byteArray) 
      buf.append(String.format("%02X", b)); 
     String hexStr = buf.toString(); 
     return hexStr; 
    } 
} 
+0

在所有這些場合,當您解密時,您是否收到原始文本? – MikeC

+0

謝謝你我認爲@Artjom B.剛剛解決了我的問題 –

回答

3

您正在使用使用初始化向量(IV)的CBC模式。由於您沒有在代碼中指定IV,因此每次調用代碼時都會隨機生成它。這是一個重要的屬性,以防止密文的觀察者確定是否有再次發送的消息。這是實現語義安全所必需的。

由於IV是隨機生成的,因此在解密過程中也需要與在加密過程中使用的IV相同的IV。 IV不一定是保密的,但它需要不可預知(它是)。一種常見的方法是將它寫在密文前,並在解密期間將其讀回。它始終具有與塊大小相同的長度。 AES的大小爲16字節。

+0

非常感謝!順便說一句,你能舉出一個使用IV的「常用方式」的例子嗎? –

+1

在你的情況下,一個簡單的'return byteToHex(cipher.getIV())+ byteToHex(cipher.doFinal(plainText.getBytes()));'應該在解密過程中使用子字符串。如果你想讓你的加密工作在大數據上,那麼你應該使用流。 –

相關問題