如何为SHA256获取Ruby生成的HMAC,以便安全地匹配Java? [英] How to get Ruby generated HMAC for SHA256 that is url safe to match Java?

查看:147
本文介绍了如何为SHA256获取Ruby生成的HMAC,以便安全地匹配Java?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个运行一些Java代码的tomcat服务器,允许用户使用API​​密钥进行身份验证。该请求使用使用SHA256创建的HMAC。我有一个Ruby客户端,我用它来发出请求,因为我刚接触加密,我很难让它生成匹配的HMAC。我试过不把它设为URL安全,并且匹配。所以我真的很想知道如何让Ruby客户端与URL安全版本匹配(因为我无法更改Java代码)。它最后只有一个额外的=字符。在此先感谢您的帮助。

I have a tomcat server running some Java code that lets users authenticate using an API key. The request uses an HMAC created with SHA256. I have a Ruby client that I am using to make the request and since I'm new to encryption I am having a difficult time getting it to generate a matching HMAC. I have tried not making it URL safe, and that matches. So I'm really wondering is how I can get the Ruby client to match with the URL safe version (since I can't change the Java code). It's just got an extra = character at the end. Thanks in advance for any help.

对于Ruby我使用的是1.9.3而对于Java我使用的是6u31以及来自apache的commons-codec-1.6.jar库。

For Ruby I am using 1.9.3 and for Java I am using 6u31 along with the commons-codec-1.6.jar library from apache.

代码

Ruby:

require "openssl"
require "base64"

json_str = "{'community':'LG7B734A', 'login_id':'user1', 'time':'1331928899'}"
digest = OpenSSL::Digest::Digest.new("sha256")
key = [ "4cc45e4258121c3fec84147673e1bd88e51b1c177aafcfa2da72bd4655c9f933" ]
hmac = OpenSSL::HMAC.digest(digest, key.pack("H*"), json_str)

encoded_url_safe = Base64.urlsafe_encode64(hmac)
encoded = Base64.encode64(hmac)

puts("Encoded (Url Safe): " + encoded_url_safe)
puts("Encoded           : " + encoded)

Java:

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;

public class ExampleHMAC
{
    public static void main(String[] args) throws Exception
    {
        String key = "4cc45e4258121c3fec84147673e1bd88e51b1c177aafcfa2da72bd4655c9f933";
        byte[] keyBytes = Hex.decodeHex(key.toCharArray());

        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "HmacSHA256");
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(keySpec);

        String jsonStr = "{'community':'LG7B734A', 'login_id':'user1', 'time':'1331928899'}";
        byte[] hmacBytes = mac.doFinal(jsonStr.getBytes());

        String encodedUrlSafe = Base64.encodeBase64URLSafeString(hmacBytes);
        String encoded = Base64.encodeBase64String(hmacBytes);

        System.out.println("Encoded (Url Safe): " + encodedUrlSafe);
        System.out.println("Encoded           : " + encoded);
    }
}

输出

Ruby:

Encoded (Url Safe): QgYLqGm1M4qozdEjGC_CnJ8CdBm2jQpsU85kSWFcjKM=
Encoded           : QgYLqGm1M4qozdEjGC/CnJ8CdBm2jQpsU85kSWFcjKM=

Java:

Encoded (Url Safe): QgYLqGm1M4qozdEjGC_CnJ8CdBm2jQpsU85kSWFcjKM
Encoded           : QgYLqGm1M4qozdEjGC/CnJ8CdBm2jQpsU85kSWFcjKM=


推荐答案

Ruby不会删除尾随的'=' - 这不是绝对的要求,因为您可以阅读RFC 4648 它只是声明在某些应用中可能需要删除它们。但除此之外,保证Ruby的URL安全编码与Java完全相同。

Ruby does not remove the trailing '=' - it is not an absolute requirement, as you can read in RFC 4648 it just states that removing them might be desirable in certain applications. But other than that it is guaranteed that Ruby's URL-safe encoding will be exactly the same as Java's.

所以你唯一要做的就是去除尾随' ==',你可以使用正则表达式:

So the only thing for you to do is strip off the trailing '==', you could for example use a regex:

encoded_url_safe_.gsub!(/=+$/, "")

这篇关于如何为SHA256获取Ruby生成的HMAC,以便安全地匹配Java?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆