Java中的加密我需要一个16字节的初始向量

时间:2014-03-27 04:02:04

标签: java encryption aes

您好我正在尝试使用带有initalvector和密钥的AES加密来加密字符串。问题是我无法生成16字节长的IV。我做什么它显示IV不是16字节所以引发异常。

 public static String encryptString(String str){
        char[] CHARSET_AZ_09 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
        String initialVectorString = Helper.randomString(CHARSET_AZ_09, 16);
        byte[] vectorbytes = (new org.apache.commons.codec.binary.Base64()).encode(initialVectorString.getBytes());

        String encryptedString = Helper.encrypt(str, initialVectorString, "mykey");
        return encryptedString;
    }
    public static String randomString(char[] characterSet, int length) {
        Random random = new SecureRandom();
        char[] result = new char[length];
        for (int i = 0; i < result.length; i++) {
            // picks a random index out of character set > random character
            int randomCharIndex = random.nextInt(characterSet.length);
            result[i] = characterSet[randomCharIndex];
        }
        String str = new String(result);
        try{
            str = new String(str.getBytes(),"UTF8");
        }
        catch(Exception e){

        }
        Log.d("check",str.getBytes().length+"");
        return str;
    }
    public static String encrypt(String data,String initialVectorString,String secretKey){
        String encryptedString = null;
        try{
             SecretKeySpec skeySpec = new SecretKeySpec(md5(secretKey).getBytes(), "AES");
             IvParameterSpec initialVector = new IvParameterSpec((new org.apache.commons.codec.binary.Base64()).decode(initialVectorString.getBytes()));
             Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding");
             cipher.init(Cipher.ENCRYPT_MODE, skeySpec, initialVector);
             byte[] plainTextByteArray = (new org.apache.commons.codec.binary.Base64()).decode(data.getBytes());
             byte[] encryptedByteArray = cipher.doFinal(plainTextByteArray);
             encryptedString = new String(encryptedByteArray, "UTF8");
        }
        catch (Exception e) {
            Log.d("Problem decrypting the data", e.getLocalizedMessage());
        }
        return encryptedString;
    }

有谁知道如何生成一个16字节长的IV?

2 个答案:

答案 0 :(得分:3)

您是否在询问如何创建一个16字节的数组?

byte[] iv = new byte[ 16 ];

当我们在这里时,使用它来填充随机数据:

SecureRandom random = SecureRandom.getInstance( "SHA1PRNG" );
random.nextBytes( iv );

答案 1 :(得分:1)

您获取IV值的方法非常糟糕:

String initialVectorString = Helper.randomString(CHARSET_AZ_09, 16);
// ....
IvParameterSpec initialVector = new IvParameterSpec(
    (new org.apache.commons.codec.binary.Base64()).decode(
    initialVectorString.getBytes()));

看起来您正在创建一个16个字符的字母数字字符串,然后将其视为base64编码的数据(它不是)并将该结果用作IV。很奇怪!

相反,只需使用Random类生成随机字节。我建议Random足以产生公共IV值,但如果你觉得超级偏执,你可以使用SecureRandom

byte[] iv = new byte[16];
random.nextBytes(iv); // where 'random' is a private static final field of 
                      // your class, with type Random