生成AES密钥

时间:2013-11-25 22:15:08

标签: java encryption aes

我在互联网上找到了这个:http://www.code2learn.com/2011/06/encryption-and-decryption-of-data-using.html

基本上,我想做的不是像

那样设置密钥
  new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't',
'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };

我希望它是随机的(但必须是16个字节),并且可以访问它(在屏幕上打印)。还有,有没有办法将其设置为字符串,而不是字节类型?

2 个答案:

答案 0 :(得分:6)

强AES密钥长度为16,24或32 字节。如果将键限制为映射到可打印US-ASCII字符的字节,则键将弱于预期,因为其范围有限(大约100位,而不是128倍数百倍)。最好使用十六进制,base-64或base-85等编码将密钥表示为文本;当然,这些陈述会更长。

要创建安全密钥,请使用基于正确播种的加密随机数生成器的KeyGenerator;如果您没有指定RNG,提供商将选择自己的RNG:

KeyGenerator gen = KeyGenerator.getInstance("AES");
gen.init(128); /* 128-bit AES */
SecretKey secret = gen.generateKey();
byte[] binary = secret.getEncoded();
String text = String.format("%032X", new BigInteger(+1, binary));
System.out.println(text);

如果需要,可以使用首选算法和提供程序实例化自己的SecureRandom实例,并通过init()方法的重载将其传递给密钥生成器。

有一些关键的派生方法试图减轻基于密码的密钥的弱点,但基于密码的密钥总是更容易预测。

答案 1 :(得分:1)

  

基本上,我想做的不是像

那样设置密钥


new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't', 'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };

很好,因为这很糟糕且不安全。这是最糟糕的秘密密钥。密码不是密钥,不应该这样使用。

  

我希望它是随机的(但必须是16个字节)

您希望它是安全随机的:

public static void main(final String ... args) throws Exception {
    final SecureRandom prng = new SecureRandom();
    final byte[] aes128KeyData  = new byte[128 / Byte.SIZE];
    prng.nextBytes(aes128KeyData);
    final SecretKey aesKey = new SecretKeySpec(aes128KeyData, "AES");
    System.out.println(toHex(aesKey.getEncoded()));
}

private static String toHex(final byte[] data) {
    final StringBuilder sb = new StringBuilder(data.length * 2);
    for (final byte b : data) {
        sb.append(String.format("%02X", b));
    }
    return sb.toString();
}
  

并可以访问它(在屏幕上打印)。

见上文。

  

另外,有没有办法将其设置为字符串,而不是字节类型?

嗯,是的,你可以解码上面的十六进制字符串。但最终AES算法需要二进制密钥,二进制明文并将生成二进制输出。 SecretKey类只不过是字节数组的包装器。

要与字符串进行更多转化,请了解 ...