【问题标题】:Compute HMAC sha-512 in NodeJS and Java在 NodeJS 和 Java 中计算 HMAC sha-512
【发布时间】:2019-06-22 23:37:12
【问题描述】:

我正在尝试将 sha-512 计算从 java 迁移到节点 JS,但我似乎无法获得相同的结果...

Java 代码(从 what I saw online 看来是标准的):

public class Test
{
    private static String get_SecurePassword(String passwordToHash, String salt, String algo) throws NoSuchAlgorithmException
    {
        String generatedPassword = null;

        MessageDigest md = MessageDigest.getInstance(algo);
        md.update(salt.getBytes());
        byte[] bytes = md.digest(passwordToHash.getBytes());
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i< bytes.length; i++) {
            sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
        }

        generatedPassword = sb.toString();

        return generatedPassword;
    }

    public static void main(String[] args) throws NoSuchAlgorithmException
    {
        String res = get_SecurePassword("test", "test", "SHA-512");

        System.out.println(res);
    }
}

输出:

125d6d03b32c84d492747f79cf0bf6e179d287f341384eb5d6d3197525ad6be8e6df0116032935698f99a09e265073d1d6c32c274591bf1d0a20ad67cba921bc

NodeJS:

const crypto = require('crypto');

function getSecurePassword(password, salt, algo) {
    const algoFormatted = algo.toLowerCase().replace('-', '');
    const hash = crypto.createHmac(algoFormatted, salt);
    hash.update(password);

    const res = hash.digest('hex');

    return res;
}

console.log(getSecurePassword('test', 'test', 'SHA-512'));

输出:

9ba1f63365a6caf66e46348f43cdef956015bea997adeb06e69007ee3ff517df10fc5eb860da3d43b82c2a040c931119d2dfc6d08e253742293a868cc2d82015

我做错了什么?

注意:我使用的是 Java 8 和 Node 10.13

【问题讨论】:

  • 根据Freeformatter,您的 NodeJS 结果是正确的。
  • 您在调用getBytes() 时未指定字符编码。根据您的数据和系统上的默认平台编码,这可能会更改您为盐和明文传递的内容。
  • 哦……所以Java代码不是标准的sha-512?如果是这样,我该如何复制它? @宪兵
  • 感谢@DavidConrad,我尝试在 Java 代码中添加编码,但这没有帮助(两个代码都在同一个系统上运行)

标签: java node.js hmac sha512


【解决方案1】:

在 Node 中,您使用 HMAC-SHA-512,但在 Java 中,您只是使用 SHA-512 并将密钥和明文连接起来。这不是 HMAC 的工作方式。您还需要在 Java 中使用 HMAC-SHA-512:

import static java.nio.charset.StandardCharsets.*;

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class Test {
    private static String getSecurePassword(String password, String salt, String algo)
            throws NoSuchAlgorithmException, InvalidKeyException {
        SecretKeySpec secretKeySpec = new SecretKeySpec(salt.getBytes(UTF_8), algo);
        Mac mac = Mac.getInstance(algo);
        mac.init(secretKeySpec);
        byte[] bytes = mac.doFinal(password.getBytes(UTF_8));

        return new BigInteger(1, bytes).toString(16);
    }

    public static void main(String[] args)
            throws NoSuchAlgorithmException, InvalidKeyException {
        System.out.println(getSecurePassword("test", "test", "HmacSHA512"));
    }
}

输出:

9ba1f63365a6caf66e46348f43cdef956015bea997adeb06e69007ee3ff517df10fc5eb860da3d43b82c2a040c931119d2dfc6d08e253742293a868cc2d82015

【讨论】:

  • 我实际上需要反过来(修复 JS 代码),但这有帮助! :) 谢谢!!!
【解决方案2】:

如果有人正在寻找我感谢@DavidConrad 所做的 Node JS 修复,这里是:

const crypto = require('crypto');

function getSecurePassword(password, salt, algo) {
    const algoFormatted = algo.toLowerCase().replace('-', '');
    const hash = crypto.createHash(algoFormatted);
    hash.update(salt + password);

    return hash.digest('hex');
}

console.log(getSecurePassword('test', 'test', 'SHA-512'));

输出:

125d6d03b32c84d492747f79cf0bf6e179d287f341384eb5d6d3197525ad6be8e6df0116032935698f99a09e265073d1d6c32c274591bf1d0a20ad67cba921bc

【讨论】:

    【解决方案3】:

    对于NodeJS,你可以在key中追加数据,得到Java等价的hash。

    require('crypto').createHash(algo).update(data + key).digest()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-13
      • 2014-08-15
      • 2011-10-21
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多