【问题标题】:Reliable implementation of PBKDF2-HMAC-SHA256 for JAVAPBKDF2-HMAC-SHA256 for JAVA 的可靠实现
【发布时间】:2014-04-30 02:59:18
【问题描述】:

2019 年更新:Bouncycastle 现在支持 PBKDF2-HMAC-SHA256,因为 bouncycastle 1.60


对于 JAVA 是否有可靠的 PBKDF2-HMAC-SHA256 实现?

我曾经使用 bouncycastle 加密,但它不提供 PBKDF2WithHmacSHA256'。

我不想自己写加密模块。

您能否推荐任何替代库或算法(如果我可以坚持使用 bouncycastle)

(这里是 bouncycastle 支持的算法) http://www.bouncycastle.org/specifications.html

【问题讨论】:

标签: java cryptography bouncycastle pbkdf2


【解决方案1】:

直接使用 BouncyCastle 类:

PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest());
gen.init("password".getBytes("UTF-8"), "salt".getBytes(), 4096);
byte[] dk = ((KeyParameter) gen.generateDerivedParameters(256)).getKey();

【讨论】:

    【解决方案2】:

    它在 Java 8 中可用:

    public static byte[] getEncryptedPassword(
                                             String password,
                                             byte[] salt,
                                             int iterations,
                                             int derivedKeyLength
                                             ) throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeySpec spec = new PBEKeySpec(
                                     password.toCharArray(),
                                     salt,
                                     iterations,
                                     derivedKeyLength * 8
                                     );
    
        SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
    
        return f.generateSecret(spec).getEncoded();
    }
    

    【讨论】:

    • 奇怪,我无法让 Java 8 版本正常工作。它生成了输出,但输出不同于 Bouncy Castle 和等效的 Node.js
    • @Kirby 确保你只使用 ASCII,Java 8 有点奇怪,因为它只使用 char 的低 8 位(即 Windows-1252 兼容的字符编码)。跨度>
    • 像魅力一样工作。顺便说一句,如果您想使用 512 字节的摘要,只需将“PBKDF2WithHmacSHA256”更改为“PBKDF2WithHmacSHA512”即可。
    • @MaartenBodewes 它使用UTF8.encodechar[] 转换为ByteBuffer。 IE。 7 位 ASCII 以外的任何内容都会生成多字节序列,如果与 UTF-16 字节序列进行比较,这会给您带来意想不到的结果,但这是因为编码是意外的,而不是因为 Java 忽略了某些东西。
    • @toolforger 来自PBEKeySpec (Java 14):不同的 PBE 机制可能会占用每个密码字符的不同位。例如,PKCS #5 中定义的 PBE 机制只查看每个字符的低 8 位,而 PKCS #12 则查看每个字符的所有 16 位。 PKCS#5 中指定了 PBKDF2。因此,如果使用 UTF-8,那么文档就不合适了。你能说明你在哪里找到了编码函数吗?
    【解决方案3】:

    使用 spongycastle(android 上的 java)

    如果你直接在 java 上使用 bouncycastle 的话,用 bouncycastle 替换 spongycastle

    import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
    import org.spongycastle.crypto.digests.SHA256Digest;
    import org.spongycastle.crypto.params.KeyParameter;
    
    public class Crypto {
        public String pbkdf2(String secret, String salt, int iterations, int keyLength) {
            PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest());
            byte[] secretData = secret.getBytes();
            byte[] saltData = salt.getBytes();
            gen.init(secretData, saltData, iterations);
            byte[] derivedKey = ((KeyParameter)gen.generateDerivedParameters(keyLength * 8)).getKey();    
            return toHex(derivedKey);
        }
    
        private static String toHex(byte[] bytes) {
            BigInteger bi = new BigInteger(1, bytes);
            return String.format("%0" + (bytes.length << 1) + "x", bi);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-05-29
      • 1970-01-01
      • 2013-12-01
      • 1970-01-01
      • 2014-07-19
      • 2011-01-28
      • 1970-01-01
      • 2019-01-08
      • 2012-07-22
      相关资源
      最近更新 更多