HMC SHA1 哈希 - Java 生成与 C# 不同的哈希输出

2024-03-29

这是后续this https://stackoverflow.com/questions/7175067/hmc-sha1-hash-c-sharp-producing-different-hash-output-than-ruby问题,但我正在尝试将 C# 代码移植到 Java,而不是将 Ruby 代码移植到 C#,就像相关问题中的情况一样。我正在尝试验证加密的签名 http://docs.recurly.com/recurlyjs/signatures从 Recurly.js api 返回是有效的。不幸的是,Recurly 没有 Java 库来协助验证,因此我必须自己实现签名验证。

根据上述相关问题(this https://stackoverflow.com/questions/7175067/hmc-sha1-hash-c-sharp-producing-different-hash-output-than-ruby),以下 C# 代码可以生成验证从 Recurly 返回的签名所需的哈希值:

var privateKey = Configuration.RecurlySection.Current.PrivateKey;
var hashedKey = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(privateKey));
var hmac = new HMACSHA1(hashedKey);
var hash = hmac.ComputeHash(Encoding.ASCII.GetBytes(dataToProtect));
return BitConverter.ToString(hash).Replace("-", "").ToLower();

Recurly 提供了以下有关其的示例数据签名 http://docs.recurly.com/recurlyjs/signatures文档页面:

未加密的验证消息: [1312701386,transactioncreate,[账户代码:ABC,金额:5000,货币:美元]]

私钥: 0123456789ABCDEF0123456789ABCDEF

生成的签名: 0f5630424b32402ec03800e977cd7a8b13dbd153-1312701386

这是我的 Java 实现:

String unencryptedMessage = "[1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]";
String privateKey = "0123456789ABCDEF0123456789ABCDEF";
String encryptedMessage = getHMACSHA1(unencryptedMessage, getSHA1(privateKey));

private static byte[] getSHA1(String source) throws NoSuchAlgorithmException, UnsupportedEncodingException{
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    byte[] bytes = md.digest(source.getBytes("UTF-8"));
    return bytes;
}

private static String getHMACSHA1(String baseString, byte[] keyBytes) throws GeneralSecurityException, UnsupportedEncodingException {
    SecretKey secretKey = new SecretKeySpec(keyBytes, "HmacSHA1");
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(secretKey);
    byte[] bytes = baseString.getBytes("ASCII");
    return Hex.encodeHexString(mac.doFinal(bytes));
}

但是,当我打印出 cryptoMessage 变量时,它与示例签名的消息部分不匹配。具体来说,我得到的值是“c8a9188dcf85d1378976729e50f1de5093fabb78”,而不是“0f5630424b32402ec03800e977cd7a8b13dbd153”。

Update

根据@M.Babcock,我使用示例数据重新运行了 C# 代码,它返回了与 Java 代码相同的输出。所以看来我的散列方法是正确的,但我传递了错误的数据(未加密的消息)。叹。如果/当我可以确定要加密的正确数据是什么时,我将更新这篇文章 - 因为 Recurly 文档中提供的“未加密验证消息”似乎缺少某些内容。

Update 2

错误结果是“未加密的验证消息”数据/格式。示例数据中的消息实际上并未加密到提供的示例签名 - 所以文档可能已经过时了?无论如何,我已经确认 Java 实现适用于现实世界的数据。谢谢大家。


我认为问题出在您的 .NET 代码中。做Configuration.RecurlySection.Current.PrivateKey返回一个字符串?该值是您期望的键吗?

使用以下代码,.NET 和 Java 返回相同的结果。

.NET代码

string message = "[1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]";
string privateKey = "0123456789ABCDEF0123456789ABCDEF";

var hashedKey = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(privateKey));
var hmac = new HMACSHA1(hashedKey);
var hash = hmac.ComputeHash(Encoding.ASCII.GetBytes(message));

Console.WriteLine("  Message: {0}", message);
Console.WriteLine("      Key: {0}\n", privateKey);
Console.WriteLine("Key bytes: {0}", BitConverter.ToString(hashedKey).Replace("-", "").ToLower());
Console.WriteLine("   Result: {0}", BitConverter.ToString(hash).Replace("-", "").ToLower());

Result:



  Message: [1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]
      Key: 0123456789ABCDEF0123456789ABCDEF

Key bytes: 4d857d2408b00c3dd17f0c4ffcf15b97f1049867
   Result: c8a9188dcf85d1378976729e50f1de5093fabb78
  

Java

String message = "[1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]";
String privateKey = "0123456789ABCDEF0123456789ABCDEF";

MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] keyBytes = md.digest(privateKey.getBytes("UTF-8"));

SecretKey sk = new SecretKeySpec(keyBytes, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(sk);
byte[] result = mac.doFinal(message.getBytes("ASCII"));

System.out.println("  Message: " + message);
System.out.println("      Key: " + privateKey + "\n");
System.out.println("Key Bytes: " + toHex(keyBytes));
System.out.println("  Results: " + toHex(result));

Result:



  Message: [1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]
      Key: 0123456789ABCDEF0123456789ABCDEF

Key Bytes: 4d857d2408b00c3dd17f0c4ffcf15b97f1049867
  Results: c8a9188dcf85d1378976729e50f1de5093fabb78
  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HMC SHA1 哈希 - Java 生成与 C# 不同的哈希输出 的相关文章

随机推荐

  • 如何在没有竞争条件的情况下重命名()?

    如果我想重命名A to B 但前提是B不存在 天真的事情会检查是否B存在 与access B F OK 或类似的东西 如果不继续rename 不幸的是 这会打开一个窗口 在此期间其他进程可能会决定创建B 然后它被覆盖 更糟糕的是没有迹象表明
  • 如何使用 GStreamer 和 XOverlay 在 GTK+ 应用程序窗口中嵌入视频?

    我正在尝试使用 GTK 和 GStreamer 编写一个小型媒体播放器 目前使用 XOverlay 接口将视频嵌入到 GtkDrawing 区域中INSIDE主窗口 该程序是使用以下命令编译的 g home phongcao cacao c
  • `rand()` 的用处 - 或者谁应该调用 `srand()`?

    背景 我用的是rand std rand std random shuffle 以及我的代码中用于科学计算的其他函数 为了能够重现我的结果 我总是明确指定随机种子 并通过srand 直到最近我才发现 libxml2 也会调用srand 懒洋
  • Chrome 扩展程序将消息从 iFrame 发送到事件页面,然后发送到内容脚本

    我已经从内容脚本插入了一个 iframe 效果很好 但是如果我想在 iframe 上显示父级的 html 内容 我必须使用消息传递在 iframe 和内容脚本之间进行通信 但它不起作用 然后我尝试将消息从 iframe 发送到 事件页面 然
  • OSX 上的 mongodb:如何更新 brew 服务以通过身份验证启动?

    我用自制软件安装了 mongodb 我添加了一个 admin 并更新了 usr local etc mongod conf 以启用安全授权 我可以使用 auth 启动 mongod mongod auth port 27017 dbpath
  • 按日期连接两个 data.table,表 1 中最接近的日期严格小于第二个表中的日期

    从 SO 上其他地方窃取一个虚拟示例 按确切日期加入 data table 如果不是 则按最近的小于日期加入 data table https stackoverflow com questions 11341557 join data t
  • Graphviz中如何使边重叠?

    我想在 graphviz 中使边缘重叠 但 graphviz 似乎重新排列了叶节点以避免重叠 我可以强制 graphviz 停止重新排列节点吗 制作 Desired 我正在使用 pygraphviz 创建树 使用以下方法额外的隐形边缘非常适
  • 使用 SelectionModel 或 ListDataProvider 选择 CellList 中的元素

    我使用 CellList 列出数据 使用 ListDataProvider 管理数据 使用 SelectionModel 从 CellList 中选择元素并相应地生成事件 现在 当我使用 cellList getList set index
  • 使用Azure B2C登录时如何在自定义页面中嵌入登录控件

    我正在使用 Azure AD B2C 示例 出于测试目的 我使用稍作修改的单页应用程序sample https github com Azure Samples active directory b2c javascript msal si
  • 如何防止创建空对象

    我正在尝试将每个列表都位于嵌套对象内部的网络服务模型映射到更简单的东西 Model 1 public class Parent private Children children public class Children private
  • 如何在Python中从邻接矩阵创建边列表数据框?

    我有一个 pandas 数据框 将其视为网络中节点的加权邻接矩阵 的形式 df A B C D A 0 0 5 0 5 0 B 1 0 0 0 C 0 8 0 0 0 2 D 0 0 1 0 我想获得一个代表边缘列表的数据框 对于上面的例子
  • PHPstorm项目导航

    如何在PHPstorm项目列表中选择打开的文件 我的意思是 PHPstorm 有一个 在项目中选择 Netbeans 功能的模拟 Navigate View在旧版本中 Select In Project View 也可以启用Autoscro
  • NuGet 将 DLL 文件放在哪里?

    我正在尝试解决 NuGet 的问题源代码控制限制 https stackoverflow com questions 7015149 multiperson team using nuget and source control 为此 我需
  • 使用关联数组作为 D3 的数据

    我有一个非常简单的 D3 示例 它首先将数据读入关联数组 然后将其显示在条形图中 不过 我似乎无法使用此方法显示任何内容 相反 我必须在两者之间插入一个任务 将数据读取到关联数组中 将该数据复制到一个简单数组中 然后使用该简单数组显示条形图
  • 获取可用(语言)resx 文件的列表

    许多程序都有社区 在应用程序发布后向其添加语言 因此 在程序的设置窗口中 人们可以看到可用语言的下拉列表 那么 人们在使用 resx 文件进行本地化时如何编码呢 我在网上搜索了一遍又一遍 但找不到任何答案 一切都运行良好 但现在 我需要制作
  • 如何在 pom.xml 文件中指定 Java 编译器版本?

    我在 Netbeans 中编写了一些 Maven 代码 大约有 2000 多行 当我在 Netbeans 上编译它时 一切都很好 但如果我想在命令行上运行它 我会收到以下错误 generics are not supported in so
  • JavaScript 风格的警报系统

    我在用smoke js http ssssnakes com smoke 它允许设置经典警报 javascript 窗口的样式 您所要做的就是放置 smoke在警报之前 即 smoke confirm 我遇到的问题是确定 取消回调 它对我不
  • 创建“拼写检查”,以合理的运行时间检查数据库

    我不是在询问如何实现拼写检查算法本身 我有一个包含数十万条记录的数据库 我想要做的是针对所有这些记录的表中的特定列检查用户输入 并返回具有特定汉明距离的任何匹配项 同样 这个问题不是关于确定汉明距离等 当然 目的是创建一个 您的意思是 功能
  • pyspark 中的交叉验证

    我使用交叉验证来训练线性回归模型 使用以下代码 from pyspark ml evaluation import RegressionEvaluator lr LinearRegression maxIter maxIteration m
  • HMC SHA1 哈希 - Java 生成与 C# 不同的哈希输出

    这是后续this https stackoverflow com questions 7175067 hmc sha1 hash c sharp producing different hash output than ruby问题 但我正