【问题标题】:Why PBE generates same key with different salt and iteration count?为什么 PBE 生成具有不同盐和迭代次数的相同密钥?
【发布时间】:2012-07-24 22:22:36
【问题描述】:

我正在尝试测试 PBE 加密/解密。我发现 PBE 生成具有不同盐和迭代次数的相同密钥。当然,使用的密码是一样的。 据我了解,相同的密码和不同的盐/迭代应该得到不同的密钥。 下面是我的测试代码:

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

【问题讨论】:

    标签: passwords key iteration salt


    【解决方案1】:

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

    我搜索了 PBEWithSHA1andDESede 并找到了这个示例:http://cryptofreek.org/2010/06/04/encrypting-and-decrypting-files-with-java,其中他使用new PBEKeySpec(password) 单独指定了密钥,并使用盐和迭代计数创建了一个单独的PBEParameterSpec,然后将其传递给 Cipher.init()。

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

    【讨论】:

    • 感谢 tbroberg 的回复。 1,“盐和迭代计数恰好匹配”。盐和迭代计数是随机生成的,我认为它们不能与此测试的每次运行相匹配。 2,“你在盐和计数被塞进密码之前就停下来了”。您的意思是盐和迭代计数仅在执行加密/解密时生效? 3,我发现键总是“70 61 73 73 77 6f 72 64”。我认为这是“密码”,它与盐或迭代计数无关。这是正确的结果吗?
    • #2 和#3 似乎可以解释这种情况。我试图继续加密一些文本,每次加密的数据都不一样。所以我现在的结论是:SecretKeyFactory.generateSecret() 生成的密钥只和密码有关。至少从比较的角度来看这是正确的,即 key.getEncoded() 是相同的。 Salt和迭代计数在加密明文时生效。再次感谢您的帮助!
    • 太棒了! (#1 是个玩笑。)如果您发现答案有用,请标记它。 :^)
    • 我会这样做的。不过,我的名声太低了。我只能接受它,但不能将其标记为有用。我很抱歉我现在不能这样做。我保证会回来标记它:)
    【解决方案2】:

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

            String algo = "PBKDF2WithHmacSHA1";
    

    ...

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

    我进行了测试,结果是:false

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-10
      • 2012-08-02
      • 2012-08-13
      • 2012-06-08
      • 1970-01-01
      • 2020-12-20
      • 2011-01-14
      • 2023-01-19
      相关资源
      最近更新 更多