【发布时间】:2012-01-30 05:38:20
【问题描述】:
我正在尝试将密码安全地存储在数据库中,为此我选择存储使用 PBKDF2 函数生成的哈希值。我想使用充气城堡库来做到这一点,但我不知道为什么我不能通过使用 JCE 接口让它工作......
问题在于以 3 种不同的模式生成哈希:
1.使用sun提供的PBKDF2WithHmacSHA1密钥工厂
2.直接使用充气城堡api
3.通过JCE使用充气城堡
产生 2 个不同的值:一个与前两个通用,一个与第三个通用。
这是我的代码:
//Mode 1
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec keyspec = new PBEKeySpec("password".toCharArray(), salt, 1000, 128);
Key key = factory.generateSecret(keyspec);
System.out.println(key.getClass().getName());
System.out.println(Arrays.toString(key.getEncoded()));
//Mode 2
PBEParametersGenerator generator = new PKCS5S2ParametersGenerator();
generator.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(("password").toCharArray()), salt, 1000);
KeyParameter params = (KeyParameter)generator.generateDerivedParameters(128);
System.out.println(Arrays.toString(params.getKey()));
//Mode 3
SecretKeyFactory factorybc = SecretKeyFactory.getInstance("PBEWITHHMACSHA1", "BC");
KeySpec keyspecbc = new PBEKeySpec("password".toCharArray(), salt, 1000, 128);
Key keybc = factorybc.generateSecret(keyspecbc);
System.out.println(keybc.getClass().getName());
System.out.println(Arrays.toString(keybc.getEncoded()));
System.out.println(keybc.getAlgorithm());
我知道 PBKDF2 是使用 HMAC SHA1 实现的,所以这就是为什么我在最后一种方法中选择“PBEWITHHMACSHA1”作为算法,我从 bouncy castle java 文档中获取。
输出如下:
com.sun.crypto.provider.SunJCE_ae
[-53, 29, 113, -110, -25, 76, 115, -127, -64, 74, -63, 102, 75, 81, -21, 74]
[-53, 29, 113, -110, -25, 76, 115, -127, -64, 74, -63, 102, 75, 81, -21, 74]
org.bouncycastle.jce.provider.JCEPBEKey
[14, -47, -87, -16, -117, -31, 91, -121, 90, -68, -82, -31, -27, 5, -93, -67, 30, -34, -64, -40]
PBEwithHmacSHA
有什么想法吗?
【问题讨论】:
-
我不确定“模式 3”在做什么,但我会忽略它。它的输出是 160 位,而不是您要求的 128 位。 160 位是 SHA-1 哈希的大小。为了便携性,我会坚持使用“模式 1”。
-
我同意 erickson 的观点 - 您是否真的需要使用“模式 3”,或者“模式 1”是否可以用于安全存储密码?顺便说一下,这里是您的第一个问题的详细问题。
-
确实没必要。我只是想了解为什么 BouncyCastle 的 PBEWITHHMACSHA1 不做同样的事情。我同意,由于可移植性问题,我不会选择第二种方法。
-
谢谢伙计,第 1 号在工作中救了我的命:D
-
不同之处在于 BTW 如何将密码转换为字节。 pKcs5 和 pkcs12 不同(utf16 与 UTF8 相比,它有一堆可预测的 0 字节。这就是为什么我更喜欢模式 3 并希望看到一个 jce 参数来请求它。但同样,SHA1 无论如何都死了(不是在这个特定的申请,但您只是不想与审核员讨论)
标签: java bouncycastle jce pbkdf2