2016-04-24 34 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()));'应该在解密过程中使用子字符串。如果你想让你的加密工作在大数据上,那么你应该使用流。 –

相关问题