PBKDF2WithHmacSHA512 Vs. PBKDF2WithHmacSHA1
我正在研究一个Java认证子系统,该子系统规定在DB中存储密码为PBKDF2
生成的哈希,我现在正在尝试决定是否应该使用SHA1
或SHA512
作为PFR。 我仔细检查了两者的规格,但我们在数学上非常密集地跟随它。 有更好的加密理解的人可以解释PBKDF2WithHmacSHA512
与PBKDF2WithHmacSHA512
区别吗?
这是我正在尝试做的事情:
private static final int HASH_BYTE_SIZE = 64; // 512 bits private static final int PBKDF2_ITERATIONS = 1000; // generate random salt SecureRandom random = new SecureRandom(); byte salt[] = new byte[SALT_BYTE_SIZE]; // use salt size at least as long as hash random.nextBytes(salt); // generate Hash PBEKeySpec spec = new PBEKeySpec(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE); SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); // we would like this to be "PBKDF2WithHmacSHA512" instead? What Provider implements it? byte[] hash = skf.generateSecret(spec).getEncoded(); // convert hash and salt to hex and store in DB as CHAR(64)...
让我们一块一块地分解这个词:
PBKDF2--WithHmac--SHA512
让我们一个接一个地讨论它
-
PBKDF2
代表基于密码的密钥导数函数,它是PBKDF1的后继函数,用于实现伪随机函数,例如加密哈希,密码或HMAC到输入密码或密码以及salt值并重复该过程多次生成派生密钥,然后可以在后续操作中将其用作加密密钥。
-
HMAC
密钥哈希消息认证码(HMAC)的代表是用于计算涉及密码散列函数结合秘密密码密钥的消息认证码(MAC)的特定结构。 任何加密散列函数都可以用于计算HMAC; 因此,所得到的MAC算法被称为HMAC-MD5或HMAC-SHA1。
-
SHA512
嗯,你知道的..:P
现在,回到你的问题,代码行:
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
指定使用算法PDBKDF2WithHmacSHA1
。 什么时候你会这样做:
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
你告诉工厂使用算法PBDKF2WithHmacSHA512
。
实质上, PBKDF2WithHmacSHA1
和PBKDF2WithHmacSHA512
之间的主要区别在于:
-
PBKDF2WithHmacSHA1
将产生160位的散列长度 。 -
PBKDF2WithHmacSHA512
将产生512位的散列长度 。
因此后者更安全。 但双方都有争论哪些足以加密。 没有辩论。 只是说。
有关这两种算法的一些其他信息:
-
HMACSHA1
HMACSHA1是一种密钥哈希算法,它是从SHA1哈希函数构造的,并用作HMAC或基于哈希的消息认证码。 HMAC进程将秘密密钥与消息数据混合,用散列函数散列结果,再次将该散列值与密钥混合,然后第二次应用散列函数。 输出散列的长度为160位。
-
HMACSHA512
HMACSHA512是一种密钥哈希算法,它由SHA-512哈希函数构成,并用作基于哈希的消息认证码(HMAC)。 HMAC进程将密钥与消息数据混合并散列结果。 哈希值再次与密钥混合,然后第二次哈希。 输出散列的长度为512位。
主要优点是HmacWith512
比HmacWith256
更安全。 例如
HMAC_SHA1("key","The quick brown fox jumps over the lazy dog") = 0xde7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 HMAC_SHA512("key","The quick brown fox jumps over the lazy dog") = 0xb42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a
差异非常大(如图所示)。 希望能帮助到你。 🙂
编辑:正如OP提到的那样
PBEKeySpec(char[] password, byte[] salt, int iterationCount, int keyLength)
参数keyLength
用于指示变量密钥大小密码的密钥长度的首选项。 实际密钥大小取决于每个提供商的实现。 因此说,做一些事情
PBEKeySpec(password, salt, int 100, 512)
并不意味着您将使用SHA1生成512的keyLength。它只是意味着。 SHA1最多支持160位。 你不能超过这个。
至于你的第二个问题,看看HMAC-SHA1 。 有很多声明说像SHA256
这样的算法非常好,如果你是长哈希。
另外,根据NSA:
NSA规定“使用FIPS-186-2和SHA-256中规定的256位素数模数椭圆曲线的椭圆曲线公钥密码术适用于保护高达SECRET级别的机密信息。使用384位素数模数椭圆曲线和SHA-384是保护TOP SECRET信息所必需的。
我认为结合使用HMACfunctionSHA512非常安全。
SHA512属于SHA2加密散列函数系列。 由于SHA1具有理论上的弱点,并且SHA512稍微慢于SHA1(散列密码时速度越慢越好),应该通过SHA1选择SHA512(或任何SHA2系列)以用于散列密码。
实际上理解function上的差异并不简单,但您可能更有可能在Crypto SE网站上获得答案。