2012-07-26 8 views
7

我想测试PBE加密/解密。我发现PBE生成具有不同salt和迭代次数的相同密钥。当然,使用的密码是相同的。 正如我所了解的,相同的密码和不同的盐/迭代应该得到不同的密钥。 下面是我的测试代码:为什么PBE使用不同的salt和迭代计数生成相同的密钥?

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。 我做错了什么?

回答

4

你非常幸运,你的随机盐和迭代计数恰好匹配。直接去拉斯维加斯。现在。 )

我一派为PBEWithSHA1andDESede和追查这个例子:http://cryptofreek.org/2010/06/04/encrypting-and-decrypting-files-with-java其中他new PBEKeySpec(password)单独指定键并使用盐和()迭代计数,然后将其传递给Cipher.init创建一个单独的PBEParameterSpec

所以,不,你没有做错任何事情,你只是在盐和计数塞进密码之前停下来。

+0

感谢tbroberg的回复。 1,“盐和迭代计数恰好匹配”。 salt和迭代计数是随机生成的,我不认为它们可以匹配此测试的每次运行。 2,“你刚刚停止之前盐和计数塞进密码”。你的意思是加密和迭代计数只在加密/解密执行时生效? 3,我发现钥匙总是“70 61 73 73 77 6f 72 64”。我认为这是为了“密码”,它与salt或迭代计数无关。这是一个正确的结果吗? – Michael 2012-07-30 10:05:05

+0

#2和#3似乎解释了这种情况。我试着去加密一些文本,每次加密的数据都不一样。所以我现在的结论是:SecretKeyFactory.generateSecret()生成的密钥只与密码有关。至少从比较的角度来看,这是真实的,即key.getEncoded()是相同的。加密纯文本时,salt和迭代计数会生效。再次感谢你的帮助! – Michael 2012-07-30 10:30:55

+0

优秀! (#1是一个笑话。)如果你发现答案有用,请标记它。 :^) – tbroberg 2012-07-31 16:07:36

3

如果您使用PBKDF2WithHmacSHA1而不是PBEWithSHA1andDESede您的假设是有效的,因为它支持salt。你只需要一个该keyLength参数添加到PBEKeySpec

 String algo = "PBKDF2WithHmacSHA1"; 

...

 PBEKeySpec decPBESpec = new PBEKeySpec(password, salt, iterationCount, 128); 

我已经运行一个测试,其结果是:false

但是,请注意,为了使加密和解密正常工作,您需要在生成密钥时使用相同的salt和迭代计数。

相关问题