2017-05-28 212 views
0

我正在尝试实现AES自定义密码加密并希望了解下面的代码。AES自定义密码密钥

我不太明白为什么当我使用假设产生SecretKey为256位的“PBKDF2WithHmacSHA256”时,为什么需要指定密钥大小256“PBEKeySpec(password,salt,65536,256)” 。

在使用我的密码+ salt生成密钥后,为什么我需要将它与SecretKeySpec作为AES算法关联。

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); 
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256); 
SecretKey tmp = factory.generateSecret(spec); 
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
+0

要清楚的是:你问的是基于密码的加密,其中使用密码来派生密钥,然后用它来加密一些其他数据而不是密码本身,对吧? –

+0

@ ArtjomB。是。我正在尝试实施基于密码的加密。而我认为我还有一个问题是加密这个用于加密数据的“密码”。 – youcanlearnanything

回答

3

为什么有必要指定密钥大小256

PBKDF2是一个灵活的基于口令的密钥导出功能。它使用一个底层哈希函数和许多迭代。它可以输出任意大小的你想要的密钥。即使在生成AES-128密钥时使用SHA-256也很常见,因为与其他散列函数(如MD5和SHA-512)(仅在x64上)相比,SHA-256不会被破坏并且速度相对较慢。慢速是PBKDF的重要因素,因为它在尝试强制密码时会直接影响攻击者。当然,你也有可调整的迭代计数。

此外,PBKDF2可以输出比底层散列函数输出大小更多的密钥材料。例如,通常要求PBKDF2的输出包含IV。在你的情况下,输出应该是384位长。

通常,不建议从PBKDF2请求更多的基础散列函数。如果你想推导IV,你也应该使用use SHA-512。只要盐是针对每次加密随机生成的,并与密文一起存储,这应该足以实现语义安全性。

因此,要回答你的问题,PBKDF2不知道你想如何使用输出。你对此负责。你必须知道你在做什么。有一百万种不同的方法来解决PBKDF对某些东西进行加密的部分。

为什么我需要将它与SecretKeySpec作为AES算法关联。

如果你想使用Cipher例如加密与AES的东西,你需要在java.security.Key对象,将解析为AES在运行时通过。该方法使用Key#getAlgorithm()方法。如果在创建SecretKeySpec时未指定"AES",则将获得InvalidKeyException

+0

你的意思是如果我想要一个用于加密的AES密钥,我可以考虑KeyGenerator.getInstance(“HmacSHA256”)通过KeyGenerator.getInstance(“AES”)?和kgen.init(128);我可以指出我是否需要128位或256位密钥。 – youcanlearnanything

+0

HMAC密钥与PBKDF2的输出不同。但由于HMAC和AES不需要密钥具有任何特定的内部结构,因此可以生成HMAC密钥并将其用作AES密钥。问题是,你为什么要这样做?这对您的代码的可读性和可理解性非常不利。 –