Android AES(带密钥库)生成具有相同纯文本的不同密文

时间:2016-04-24 18:43:12

标签: java android encryption aes android-keystore

我正在尝试让Keystore帮助我生成AES加密密钥,并使用它来加密我输入的纯文本。所以这是我的代码。我在另一个活动的onCreate()方法中只调用一次createKey()方法,然后使用相同的keyAlias和相同的明文多次调用printCipherText()方法。奇怪的是:每次调用printCipherText()方法时,都会得到不同的结果。我使用相同的密钥别名和相同的明文,但为什么每次都会得到不同的密文?

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;
    }
} 

1 个答案:

答案 0 :(得分:4)

您正在使用CBC模式,该模式使用初始化向量(IV)。由于您没有在代码中指定IV,因此每次调用代码时都会随机生成IV。这是一个重要的属性,以防止密文的观察者确定是否有您再次发送的消息。这对于实现语义安全是必要的。

由于IV是随机生成的,因此您需要在解密期间使用加密期间使用的相同IV。 IV不必是秘密的,但它需要是不可预测的(它是)。一种常见的方法是将其写在密文之前,并在解密期间将其读回。它的长度始终与块大小相同。 AES的大小为16字节。