【问题标题】:Converting a hash from Java to Javascript将哈希从 Java 转换为 Javascript
【发布时间】:2021-08-26 22:42:45
【问题描述】:

我正在尝试将最初用 Java 编写的哈希函数转换为我们代码库中的 Javascript。但是,我得到了不同的结果。 下面是Java中的代码

public static String hashText(String str) {
    MessageDigest messageDigest;
    try {
        messageDigest = MessageDigest.getInstance("SHA-512");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        messageDigest = null;
    }
    byte[] bytes = str.getBytes();
    for (int i = 0; i < 64; i++) {
        messageDigest.update(bytes);
        bytes = messageDigest.digest();
    }
    hashedText = new String(Base64.encode(bytes, 2));
    return hashedText.replace(StringUtils.LF, "");
}

这是我用 Javascript 写的

function hashText(text){
  const crypto = require('crypto')
  const hash = crypto.createHash('sha512');
  const digest = hash.update(text).digest();
  return digest.toString("base64")
}
console.log(hashText(text))

我一直在试图找出我在这里做错了什么,但还没有成功。我需要帮助!

【问题讨论】:

  • java 中的 for 循环,看起来它正在重新散列 64 次。看起来你只在 javascript 中散列一次。
  • 您在 Java 中的 Base64.encode(byte[],int)java.util 或 Apache commons-codec 不匹配,所以如果它做任何奇怪的事情(我不会说非标准,因为没有明确的标准对于base64),如果没有帮助,base64的nodejs版本可能无法匹配。
  • 你的系统上 Java 的“默认字符编码”是什么?一些 ISO-8859 变体?一些 Windows 代码页? UTF-8? 'str.getBytes()' 的结果取决于该默认值。第二点:这将有助于提供一些示例输入和预期/不同的输出。
  • @RalfKleberhoff 默认为 UTF-8。我已经能够解决它,并发布了答案以防其他人需要它。谢谢

标签: java node.js react-native encryption cryptojs


【解决方案1】:

Java 中的 for 循环,看起来它正在重新散列 64 次。看起来你只在 JavaScript 中散列一次。这是一个如何在 node.js 中执行该循环的示例。

function hashText(text, iter = 1) {
  const crypto = require('crypto');
  let digest = text;
  for (let i = 0; i < iter; i++) {
    const hash = crypto.createHash('sha512');
    digest = hash.update(digest).digest();
  }
  return digest.toString('base64');
}
const text = 'asdf 1234 zxcv 5678';
console.log(hashText(text, 64));

*编辑:我不使用 java,不知道 MessageDigest.digest() 是如何工作的。具体来说:

...在进行此调用后,摘要将被重置。

在节点中,这意味着在循环的每次迭代中运行createHash。感谢@dave_thompson_085 指出这一点!

【讨论】:

  • 你是对的 nodejs 哈希不能像 Java 那样被回收,但是执行 copy after update 会给出错误的结果。使循环体 digest = hash.copy().update(digest).digest(); -- 或 digest = crypto.createHash('sha512').update(digest).digest(); 没有预先创建。
  • @David784,我刚试过你的答案,不正确。我仍然得到不同的结果
  • 感谢@dave_thompson_085,根据您的更正编辑了我的答案。
【解决方案2】:

事实证明,nodejs 加密哈希副本的工作方式有点不同。如docs 中所述,它创建了一个新的 Hash 对象,其中包含当前 Hash 对象内部状态的深层副本。但是,我需要的是使用编码字符串创建一个新的哈希。

下面是一个工作 sn-p 的示例

function hashText(text, length) {
  const crypto = require('crypto');
  let digest = text;
  for (let i = 0; i < length; i++) {
    const hash = crypto.createHash('sha512');
    hash.update(digest);
    digest = hash.digest();
  }

  return digest.toString('base64');
}
console.log(hashText(text, 64));

感谢所有以某种方式提供帮助的人

【讨论】:

    猜你喜欢
    • 2012-11-11
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 2019-05-23
    • 2018-02-23
    • 2017-07-05
    相关资源
    最近更新 更多