30

我正在研究一个 Java 身份验证子系统,该子系统将数据库中的密码存储指定为生成的PBKDF2哈希值,我现在正试图决定是否应该使用SHA1SHA512作为 PRF。我浏览了两者的规格,但它们在数学上对我来说非常密集。有更好的加密理解的人能解释一下有什么PBKDF2WithHmacSHA512不同PBKDF2WithHmacSHA1吗?

这是我正在尝试做的事情:

private static final int HASH_BYTE_SIZE = 64 * 8; // 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)...
4

2 回答 2

61

让我们逐个分解这个词:

PBKDF2--WithHmac--SHA512

让我们一步一步来

  • PBKDF2

    代表 Password-based-Key-Derivative-Function,是 PBKDF1 的继承者,用于实现伪随机函数,例如输入密码或密码短语的加密哈希、密码或 HMAC 以及盐值并重复该过程多次生成派生密钥,然后可以将其用作后续操作中的加密密钥。

  • HMAC

    Keyed-Hash Message Authentication Code (HMAC) 的代表是一种用于计算消息认证码 (MAC) 的特定结构,该结构涉及加密散列函数与秘密加密密钥的组合。任何密码散列函数,可用于计算 HMAC;生成的 MAC 算法相应地称为 HMAC-MD5 或 HMAC-SHA1。

  • SHA512

    好吧,你知道它.. :P

现在,回到你的问题,代码行:

SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

指定要使用算法的 keyFactory PDBKDF2WithHmacSHA1。当您执行以下操作时:

SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");

你告诉工厂使用算法PBDKF2WithHmacSHA512

PBKDF2WithHmacSHA1本质上,和之间的主要区别在于PBKDF2WithHmacSHA512

  1. PBKDF2WithHmacSHA1产生一个 160 位的散列长度
  2. PBKDF2WithHmacSHA512产生一个 512 位的散列长度

因此后者更安全。但双方都存在关于哪些足以加密的争论。没有辩论。只是说。

关于这两种算法的一些附加信息:

  1. HMACSHA1

    HMACSHA1 是一种基于 SHA1 散列函数的键控散列算法,用作 HMAC 或基于散列的消息身份验证代码。HMAC 过程将密钥与消息数据混合,使用散列函数对结果进行散列,再次将该散列值与密钥混合,然后再次应用散列函数。输出哈希的长度为 160 位。

  2. HMACSHA512

    HMACSHA512 是一种基于 SHA-512 散列函数构造的键控散列算法,用作基于散列的消息验证码 (HMAC)。HMAC 过程将密钥与消息数据混合,并对结果进行哈希处理。哈希值再次与密钥混合,然后进行第二次哈希。输出哈希的长度为 512 位。

主要优点是HmacWith512HmacWith256. 例如

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 指定“使用 FIPS-186-2 和 SHA-256 中指定的 256 位素数模椭圆曲线的椭圆曲线公钥密码术适用于将机密信息保护到 SECRET 级别。使用 384 位素数模数椭圆曲线和 SHA-384 是保护绝密信息所必需的。

我认为将 HMAC 函数与 SHA512 结合使用是非常安全的。

于 2013-10-13T19:19:27.793 回答
2

SHA512 属于加密哈希函数的 SHA2 系列。由于 SHA1 存在理论上的弱点,并且 SHA512 比 SHA1 稍慢(散列密码时越慢越好),为了散列密码,应该选择 SHA512(或任何 SHA2 系列)而不是 SHA1。

实际上了解功能的差异并不容易,但您可能有更好的机会在Crypto SE 网站上获得答案。

于 2013-10-13T19:13:16.130 回答