2012-04-20 338 views
4

AES密钥可以由这个代码生成是AES密钥随机?

KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
kgen.init(128); 

如果我有生成随机数,我可以用它以这样一种方式的“非常可靠”的方式

SecureRandom rnd = new SecureRandom(); 
byte[] key = new byte[16]; 
rnd.nextBytes(key); 

这种方法获得的关键是可靠的吗?

或只必须用一些特殊的算法

+2

你的问题很混乱。你能否以更清晰的方式重申你想要问的问题? – 2012-04-20 19:35:04

+0

同意脱节动词名词不要 – 2012-04-20 19:41:25

+1

[Java 256位AES密码加密](http://stackoverflow.com/questions/992019/java-256-bit-aes-password-based-encryption) 。 – kba 2012-04-20 19:45:50

回答

1

生成您可以添加使用SecureRandom随机算法:

KeyGenerator keyGen = KeyGenerator.getInstance("AES"); 
    SecureRandom random = new SecureRandom(); // cryptograph. secure random 
    keyGen.init(random); 
    SecretKey secretKey = keyGen.generateKey(); 
11

AES密钥可以是任何128位。它应该实际上是无法猜测的,无论创建它的方法。

例如:

SecureRandom sr = new SecureRandom() 

key = new byte[16]; 
iv = new byte[16]; 

sr.nextBytes(key); 
sr.nextBytes(iv); 

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key,"AES"), new IvParameterSpec(IV)); 

SecretKeySpec,顺便说一下,只是围绕字节[]瘦包装---它不以任意方式变换的关键。没有“特殊算法”。

+0

这是我想听到的,我希望这是真的:) – user249654 2012-04-20 20:16:40

+1

@ user249654是的。不要像问题那样使用普通的'java.util.Random',至少应该使用像SecureRandom这样的方法来避免快速强制你的密钥。 – 2012-04-21 14:00:03

+0

@PaŭloEbermann请同时参阅Thomas的[这个出色的问题](http://stackoverflow.com/q/18228579/589259)。这是安全的并不一定意味着它是生成密钥的最佳方法。 – 2013-08-14 12:32:31

1

听起来好像你正试图根据密码生成AES密钥。

如果是这种情况,可以使用javax.crypto.SecretKeyFactory的generateSecret方法,传入一个javax.crypto.spec.PBEKeySpec作为参数。 PBEKeySpec允许将密码指定为其构造函数的参数。

+0

是的,但我不像PBEKeySpec :) – user249654 2012-04-20 20:05:21

+0

为什么? “PBEKeySpec”有什么问题? – 2012-04-20 20:08:16

+0

我不知道什么PBEKeySpec做(在它)?:) – user249654 2012-04-20 20:14:55

3

要添加到其他的答案......我认为,基本的随机函数是不安全的原因有两方面的原因:

  1. 轻微的统计偏差是对于非安全相关的情况尚可,但是对于安全应用程序而言,这种分布的范围很窄,无法接受。
  2. 它们由系统DATETIME播种。即使知道您生成密钥的时间(精确度为+/- 6个月),也会大大降低蛮力搜索空间。
+1

请注意,这个答案是在问题从“Random”改为“SecureRandom”之前提供的*,这在我看来是作弊的。 – 2013-08-14 12:30:12