使用ripemd160和密钥对Java中的字符串进行哈希模拟php函数hash_hmac

2024-01-05

我正在尝试使用 Java 来哈希字符串ripemd160模拟以下 php 的输出:

$string = 'string';
$key = 'test';

hash_hmac('ripemd160', $string, $key);

// outputs: 37241f2513c60ae4d9b3b8d0d30517445f451fa5


尝试1

最初我尝试使用以下内容来模拟它......但是我不相信可以使用ripemd160作为 getInstance` 算法?

或者也许是这样,但我只是没有在本地启用它?

public String signRequest(String uri, String secret) {
    try {

        byte[] keyBytes = secret.getBytes();           
        SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");

        Mac mac = Mac.getInstance("ripemd160");
        mac.init(signingKey);

        // Compute the hmac on input data bytes
        byte[] rawHmac = mac.doFinal(uri.getBytes());

        // Convert raw bytes to Hex
        byte[] hexBytes = new Hex().encode(rawHmac);

        //  Covert array of Hex bytes to a String
        return new String(hexBytes, "UTF-8");
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
} 

尝试2

这促使我寻找其他方法来完成上述任务,通过 SO 和 Google,我发现 BouncyCastle 可能是更好的方法。

然后我发现这篇文章讨论了使用与我想要的相同算法的散列以及 BouncyCastle,它只是不使用密钥。 (无法在 Java 中输出正确的哈希值。怎么了? https://stackoverflow.com/questions/12303567/cannot-output-correct-hash-in-java-what-is-wrong)

public static String toRIPEMD160(String in) {
    try {
        byte[] addr = in.getBytes();
        byte[] out = new byte[20];
        RIPEMD160Digest digest = new RIPEMD160Digest();

        byte[] rawSha256 = sha256(addr);
        String encodedSha256 = getHexString(rawSha256);
        byte[] strBytes = base64Sha256.getBytes("UTF-8");
        digest.update(strBytes, 0, strBytes.length);

        digest.doFinal(out, 0);
        return getHexString(out);
    } catch (UnsupportedEncodingException ex) {
        return null;
    }
}

我已经按照预期工作了。

Issue

你会注意到,在尝试2目前无法为散列提供密钥,我的问题是如何调整此函数以能够提供密钥并完成我需要做的最后阶段才能模拟原始 php 函数:hash_hmac('ripemd160', $string, $key);


使用 Bouncy Castle 的 RIPEMD160 很好,但你必须实施HMAC https://www.ietf.org/rfc/rfc2104.txt,而不仅仅是散列您的数据。 HMac 只是H(K XOR opad, H(K XOR ipad, text)), where H是你的哈希函数,K是秘密,text消息和opad and ipad是预定义的常数。为了演示它是如何工作的,我翻译了以下内容Python的实现 https://hg.python.org/cpython/file/2.7/Lib/hmac.py:

public static String signRequest(String uri, String secret) throws Exception {
    byte[] r = uri.getBytes("US-ASCII");

    // The keys must have the same block size as your hashing algorithm, in this case
    // 64 bytes right-padded with zeros.
    byte[] k_outer = new byte[64];
    System.arraycopy(secret.getBytes("US-ASCII"), 0, k_outer, 0,
        secret.getBytes("US-ASCII").length);
    byte[] k_inner = new byte[64];
    System.arraycopy(secret.getBytes("US-ASCII"), 0, k_inner, 0, 
        secret.getBytes("US-ASCII").length);

    // You'll create two nested hashes. The inner one is initialized with the
    // key xor 0x36 (byte-wise), the other one with the key xor 0x5c.
    for(int i=0; i<k_outer.length; i++)
        k_outer[i] ^= 0x5c;
    for(int i=0; i<k_inner.length; i++)
        k_inner[i] ^= 0x36;

    // Update inner hash with the key and data you want to sign
    RIPEMD160Digest d_inner = new RIPEMD160Digest();
    d_inner.update(k_inner, 0, k_inner.length);
    d_inner.update(r, 0, r.length);

    // Update outer hash with the key and the inner hash 
    RIPEMD160Digest d_outer = new RIPEMD160Digest();
    d_outer.update(k_outer, 0, k_outer.length);

    byte[] o_inner = new byte[d_inner.getDigestSize()];
    d_inner.doFinal(o_inner, 0);
    d_outer.update(o_inner, 0, o_inner.length);

    // Finally, return the hex-encoded hash
    byte[] o_outer = new byte[d_inner.getDigestSize()];
    d_outer.doFinal(o_outer, 0);

    return new String((new Hex()).encode(o_outer), "US-ASCII");
}

Bouncy Castle 在其中实现了该算法HMac class https://people.eecs.berkeley.edu/~jonah/bc/org/bouncycastle/crypto/macs/HMac.html,所以这段代码的一个较短的变体是

public static String signRequest(String uri, String secret) throws Exception {
    byte[] r = uri.getBytes("US-ASCII");
    byte[] k = secret.getBytes("US-ASCII");

    HMac hmac = new HMac(new RIPEMD160Digest());
    hmac.init(new KeyParameter(k));
    hmac.update(r, 0, r.length);

    byte[] out = new byte[hmac.getMacSize()];
    hmac.doFinal(out, 0);

    return new String((new Hex()).encode(out), "US-ASCII");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用ripemd160和密钥对Java中的字符串进行哈希模拟php函数hash_hmac 的相关文章

随机推荐

  • 如何使用 TypeScript 和来自 github 的 Chartjs.definitelyTyped 计算出 Chartjs

    我想使用 Chartjs chartjs org 作为我的图表工具以及使用 TypeScript 的 AngularJS 我已经从 GitHub 安装了 AbsoluteTyped for Chartjs 以便将 Chartjs 图表的创建
  • Google App Maker 应用部署后无法运行

    我使用 Google App Maker 构建了一个应用程序 其中有一个通过查询参数链接到表格的建议框 该应用程序在预览模式下可以正常工作 但是当我部署它时 建议框没有提出任何建议 我之前已经部署过一次 我记得没有选择框 并且它工作正常 我
  • 它什么时候会在 Android 应用程序的 admob 上生效

    我制作了集成admob的Android应用程序 然后我在我的测试设备上运行这个应用程序 它会在屏幕上显示广告横幅 但广告的状态仍然是无效的 这让我很困惑 你知道admob什么时候激活吗 运行这个从市场商店下载的应用程序 提前致谢 AdMob
  • 测试路径/System.IO.Directory::Exists 未按预期工作

    我在使用 Powershell CmdLet 测试路径时遇到问题 我在服务器上创建了共享 Servername MyShare 它允许一组用户仅创建文件并附加数据 而其他用户只能读取和删除这些文件 第一组不允许执行任何其他操作 包括读取权限
  • 我如何在 PHPExcel 中制作项目符号列表

    我试图使用将 html 标签从 php 转换为 excelPHPExcel 一切都很顺利 除了我找不到如何制作项目符号列表 PHPExcel 中是否存在此功能 我已经扫描了 PHPExcel 的一些纪录片 但我找不到任何有关子弹的内容 我想
  • 华为系统文件“源代码与字节码不匹配”

    我们正在调试其中一个应用程序的一个问题 该问题仅影响华为设备 为了调试它 我们购买了 P20 Lite ANE LX1 我们在代码中放置了一些断点 并正在调查完整的堆栈跟踪 该设备安装了 Android 8 0 我们在 Android St
  • pthread_create() 如何工作?

    鉴于以下情况 pthread t thread pthread create thread NULL function NULL 到底是做什么的pthread create do to thread 会发生什么thread在它加入主线程并终
  • org.json.JSONException:第 550 个字符处的预期文字值

    我正在尝试从 asset 文件夹中读取 JSON 文件 但我得到以下异常 org json JSONException Expected literal value at character 550 我搜索了很多东西但没有找到任何相关的东西
  • 无法使用CSS网格实现网格布局[重复]

    这个问题在这里已经有答案了 在尝试了解有关 CSS 网格的更多信息时 我尝试创建一些不同的网格布局 我试图创建的内容如下 这是其中的一个步骤 wrapper display grid grid gap 15px grid template
  • 在Android中查看活动堆栈[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 是否可以查看 Android 中的活
  • 找不到包 java.nio.file

    我的 java 编译器找不到java nio file包裹 考虑 import java nio file public class Test public static void main String args Path current
  • 性能:(比较字符串)与(转换为整数)

    大家好 我是 Stack Overflow 的新手 对 python 也相当陌生 但我已经编写代码多年了 想知道以下哪一种性能更好 假设我已经从操作系统加载了environ 并且环境中的标志保证为 0 或 1 if environ Flag
  • HTML 有序列表缩进以保留原始编号

    我需要缩进有序列表以保持父列表项编号 我拥有的 My code ol li Item 1 li li Item 2 ol li Item 2 1 li li Item 2 2 li ol li li Item 3 li ol 等等 我现在得
  • ruby at_exit 退出状态

    我可以在 at exit 块中确定自己的进程退出状态吗 at exit do if this process status success print Success else print Failure end end 使用来自的想法ta
  • CSS/HTML:如何更改复选框输入中复选标记的颜色? [复制]

    这个问题在这里已经有答案了 如何更改 HTML 复选框输入中复选标记的颜色 这是一个纯 CSS 解决方案 不应破坏屏幕阅读器或默认用户代理操作 此外 四大浏览器的最新版本都支持这一点 如果您添加一些额外的技巧 还有其他一些浏览器 但我将把它
  • ggplot2 中的日期顺序不是按时间顺序排列的

    我正在尝试制作一个图表来描述一段时间内的人口情况 然而 日期并不是按时间顺序排列的 在导入的 CSV 中 日期全部正确且按顺序排列 但是 运行下面的代码后 所显示的图表中的日期顺序不正确 开始日期位于开始日期的中间 结束日期位于开始日期的左
  • 有没有办法使用 Web Audio API 比实时更快地采样音频?

    我正在使用 Web Audio API 并试图找到一种导入 mp3 的方法 因此这仅在 Chrome 中 并在画布上生成它的波形 我可以实时执行此操作 但我的目标是比实时执行得更快 我能够找到的所有示例都涉及在附加到 onaudioproc
  • Inno Setup - 如何显示透明的 PNG 图像?

    我想在欢迎页面上显示它 这怎么可能 在5 5 7更新 2015年12月28日 中 有32位BMP并实现了Alpha通道功能 WizardImageFile 和WizardSmallImageFile Setup 部分指令现在支持带有 Alp
  • 如何忽略不耐烦的用户的多次点击?

    我有一个查询要回答远程客户端的标准请求 标准是指它不从服务器外部获取参数 每当 任何人向某个 URL 提交请求 例如http www example com query http www example com query 他 她得到的内容
  • 使用ripemd160和密钥对Java中的字符串进行哈希模拟php函数hash_hmac

    我正在尝试使用 Java 来哈希字符串ripemd160模拟以下 php 的输出 string string key test hash hmac ripemd160 string key outputs 37241f2513c60ae4d