我正在尝试测试PBE加密/解密。我发现PBE生成具有不同盐和迭代计数的相同密钥。当然,使用的密码是相同的。 据我所知,相同的密码和不同的salt / iteration应该得到不同的密钥。 以下是我的测试代码:
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
public class PBETest
{
public static void main(String[] args)
throws Exception
{
String algo = "PBEWithSHA1andDESede";
System.out.println("====== " + algo + " ======");
char[] password = "password".toCharArray();
SecureRandom rand = new SecureRandom();
byte[] salt = new byte[32];
rand.nextBytes(salt);
int iterationCount = rand.nextInt(2048);
//encryption key
PBEKeySpec encPBESpec = new PBEKeySpec(password, salt, iterationCount);
SecretKeyFactory encKeyFact = SecretKeyFactory.getInstance(algo);
Key encKey = encKeyFact.generateSecret(encPBESpec);
System.out.println("encryptioin iteration: " + iterationCount);
//decryption key
rand.nextBytes(salt);
iterationCount = rand.nextInt(2048);
PBEKeySpec decPBESpec = new PBEKeySpec(password, salt, iterationCount);
SecretKeyFactory decKeyFact = SecretKeyFactory.getInstance(algo);
Key decKey = decKeyFact.generateSecret(decPBESpec);
System.out.println("decryptioin iteration: " + iterationCount);
System.out.println("encryption key is same as decryption key? " + encKey.equals(decKey));
}
}
我希望最终输出为false
。
我做错了吗?
答案 0 :(得分:4)
你非常幸运,你的随机盐和迭代计数碰巧匹配。直接去拉斯维加斯。现在。 ;)
我用Google搜索了PBEWithSHA1和DESede并跟踪了这个示例:http://cryptofreek.org/2010/06/04/encrypting-and-decrypting-files-with-java其中他单独使用new PBEKeySpec(password)
指定密钥,并使用salt和迭代计数创建一个单独的PBEParameterSpec
,然后传递给Cipher.init()。
所以,不,你没有做错任何事,你只是在盐和计数被塞进密码之前就停了。
答案 1 :(得分:3)
如果您使用PBKDF2WithHmacSHA1
代替PBEWithSHA1andDESede
,则您的假设可以正常运行,因为它支持盐。您只需要将keyLength
参数添加到PBEKeySpec
:
String algo = "PBKDF2WithHmacSHA1";
...
PBEKeySpec decPBESpec = new PBEKeySpec( password, salt, iterationCount, 128 );
我已经进行了测试,结果是:false
。
但是,请注意,要使加密和解密正常工作,您需要在生成密钥时使用相同的salt和迭代计数。