Java 8 vs Python 2.7 pbkdf2 散列——不同的输出散列字母大小写
Java 8 vs Python 2.7 pbkdf2 hashing -- different output hash letter casing
我之前在 Python 中编写了一个使用 PBKDF2 对目标字符串进行乱码的函数:
from hashlib import pbkdf2_hmac
from binascii import hexlify
def garbleString(string, salt, iterations, hash_algorithm):
target = str.encode(string)
dk = pbkdf2_hmac(hash_algorithm, target, salt, iterations)
hash = hexlify(dk)
return (hash, salt, iterations)
>>> garbleString("1000000000","salt",100000,'sha256')
('d973f4855206bd777b25355782f1b14bf06fb395bf49a26086035b3b8820a74b', 'salt', 100000)
根据此页面,此函数是正确的 -- 它为相同的输入生成相同的哈希值。 http://www.neurotechnics.com/tools/pbkdf2
我现在正尝试在 Java 中实现相同的功能,这是我现在的位置:
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.xml.bind.DatatypeConverter;
public class GarbledStringFactory {
private String algorithm;
public GarbledStringFactory(String algorithm){
this.algorithm = algorithm;
}
public String getGarbledString(String string, String salt, int iterations, int derivedKeyLength) throws NoSuchAlgorithmException, InvalidKeySpecException {
SecretKeyFactory f = SecretKeyFactory.getInstance(this.algorithm);
KeySpec spec = new PBEKeySpec(string.toCharArray(), salt.getBytes(), iterations, derivedKeyLength * 8);
SecretKey key = f.generateSecret(spec);
String hexStr = DatatypeConverter.printHexBinary(key.getEncoded());
return hexStr;
}
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
// TODO Auto-generated method stub
GarbledStringFactory factory = new GarbledStringFactory("PBKDF2WithHmacSHA256");
String hash = factory.getGarbledString("1000000000","salt",100000,32);
System.out.println(hash);
}
}
这会产生散列 "D973F4855206BD777B25355782F1B14BF06FB395BF49A26086035B3B8820A74B",它是相同的,只是字母大小写不同。外壳重要吗?
不,大小写无关紧要。
如果您检查散列,您会发现包含的唯一字母是从 A 到 F。这实际上不是字符串,而是 hexadecimal (base 16) number 等同于 98356763175438224738455306401383784358747884932620687880657531803811513935610 的十进制/基数。
- A₁₆(A 以 16 为基数)与 10₁₀(10 以 10 为基数)相同
- B₁₆ 是 11₁₀
- C₁₆ 是 12₁₀
- D₁₆ 是 13₁₀
- E₁₆ 是 14₁₀
- F₁₆ 是 15₁₀
数字是大写还是小写都没有关系。意思是一样的。
您可以在 Python 解释器中看到这一点,其中前导 0x
表示十六进制数:
>>> hex(12)
'0xc'
>>> 0xf
15
>>> 0xF
15
我之前在 Python 中编写了一个使用 PBKDF2 对目标字符串进行乱码的函数:
from hashlib import pbkdf2_hmac
from binascii import hexlify
def garbleString(string, salt, iterations, hash_algorithm):
target = str.encode(string)
dk = pbkdf2_hmac(hash_algorithm, target, salt, iterations)
hash = hexlify(dk)
return (hash, salt, iterations)
>>> garbleString("1000000000","salt",100000,'sha256')
('d973f4855206bd777b25355782f1b14bf06fb395bf49a26086035b3b8820a74b', 'salt', 100000)
根据此页面,此函数是正确的 -- 它为相同的输入生成相同的哈希值。 http://www.neurotechnics.com/tools/pbkdf2
我现在正尝试在 Java 中实现相同的功能,这是我现在的位置:
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.xml.bind.DatatypeConverter;
public class GarbledStringFactory {
private String algorithm;
public GarbledStringFactory(String algorithm){
this.algorithm = algorithm;
}
public String getGarbledString(String string, String salt, int iterations, int derivedKeyLength) throws NoSuchAlgorithmException, InvalidKeySpecException {
SecretKeyFactory f = SecretKeyFactory.getInstance(this.algorithm);
KeySpec spec = new PBEKeySpec(string.toCharArray(), salt.getBytes(), iterations, derivedKeyLength * 8);
SecretKey key = f.generateSecret(spec);
String hexStr = DatatypeConverter.printHexBinary(key.getEncoded());
return hexStr;
}
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
// TODO Auto-generated method stub
GarbledStringFactory factory = new GarbledStringFactory("PBKDF2WithHmacSHA256");
String hash = factory.getGarbledString("1000000000","salt",100000,32);
System.out.println(hash);
}
}
这会产生散列 "D973F4855206BD777B25355782F1B14BF06FB395BF49A26086035B3B8820A74B",它是相同的,只是字母大小写不同。外壳重要吗?
不,大小写无关紧要。
如果您检查散列,您会发现包含的唯一字母是从 A 到 F。这实际上不是字符串,而是 hexadecimal (base 16) number 等同于 98356763175438224738455306401383784358747884932620687880657531803811513935610 的十进制/基数。
- A₁₆(A 以 16 为基数)与 10₁₀(10 以 10 为基数)相同
- B₁₆ 是 11₁₀
- C₁₆ 是 12₁₀
- D₁₆ 是 13₁₀
- E₁₆ 是 14₁₀
- F₁₆ 是 15₁₀
数字是大写还是小写都没有关系。意思是一样的。
您可以在 Python 解释器中看到这一点,其中前导 0x
表示十六进制数:
>>> hex(12)
'0xc'
>>> 0xf
15
>>> 0xF
15