HMAC-SHA1计算的问题

cyber4pp 2018-01-15 04:08:55
需要计算HMAC的值,算法是 SHA1。百度到的代码计算方式都是这么算的,流程也按文档的来的,可以最后算不出DEMO给的值。以为是DEMO有错,按自己的方式计算并请求,返回信息说“参数不和法”。麻烦了解这块儿的同学给看下~

String sb="GET&%2F&AccessKeyId%3Dtestid&Action%3DChat&Format%3Dxml®ionId%3Dcn-qingdao&SignatureMethod%3DHMAC-SHA1&SignatureNonce%3D1324fd0e-e2bb-4bb1-917c-bd6e437f1710&SignatureVersion%3D1.0×tamp%3D2017-10-11T11%253A10%253A07Z&Version%3D2017-10-11";
String key="testsecret&";
SecretKey secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
System.out.println(key.getBytes());
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(secretKey);
byte[] HMAC=mac.doFinal(sb.getBytes());
String Signature=Base64.getEncoder().encodeToString(HMAC);



最后按照 Base64 编码规则把上面的 HMAC 值编码成字符串,即得到签名值
我计算的值为“v2c6rOJouaq01lhRS7OIqtP0o14=”。
DEMO给的计算值为:“SmhZuLUnXmqxSEZ%2FGqyiwGqmf%2BM=”。
...全文
625 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
cyber4pp 2018-01-18
  • 打赏
  • 举报
回复
引用 1 楼 dxbj1016 的回复:
我也对接了阿里云的服务这一块,之前的写的代码你看看

Map param = new HashMap<>();
        param.put("SignatureVersion", 1.0);
        param.put("Format", "JSON");
        param.put("Timestamp", LocalDateTime.now(ZoneId.of("UTC")).format(dtf));
        param.put("RegionId", "cn-shanghai");
        param.put("AccessKeyId", accessId);
        param.put("SignatureMethod", "HMAC-SHA1");
        param.put("Version", "2014-05-15");
        param.put("LoadBalancerId", loadId);
        param.put("Action", "SetBackendServers");
        param.put("SignatureNonce", UUID.randomUUID().toString());
        param.put("BackendServers", "[{\"ServerId\":\"" + serverId + "\",\"Weight\":\"" + weight + "\"}]");

        List<String> keyList = new ArrayList(param.keySet());
        Collections.sort(keyList);

        List<String> paramList = new ArrayList<>();
        for (String key : keyList) {
            paramList.add(String.format("%s=%s", key, URLEncoder.encode(param.get(key).toString(), "UTF-8")));
        }

        String stringToSign = "GET" + "&" + URLEncoder.encode("/", "UTF-8")
                + "&" + URLEncoder.encode(StringUtils.join(paramList, "&"), "UTF-8");

        String sign = EncodeUtil.HmacSHA1AndBase64(stringToSign, securityId);

        paramList.add(String.format("%s=%s", "Signature", URLEncoder.encode(sign, "UTF-8")));


        URL url = new URL("http://slb.aliyuncs.com/?" + StringUtils.join(paramList, "&"));
使用的jdk8的时间类 private static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"); 加密的类也是网上拿过来用的,应该都是差不多的

public static String HmacSHA1AndBase64(String encryptText, String encryptKey) throws Exception {

        byte[] data=encryptKey.getBytes("UTF-8");
        //根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
        SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
        //生成一个指定 Mac 算法 的 Mac 对象
        Mac mac = Mac.getInstance("HmacSHA1");
        //用给定密钥初始化 Mac 对象
        mac.init(secretKey);

        byte[] text = encryptText.getBytes("UTF-8");
        //完成 Mac 操作
        return Base64.encodeBase64String(mac.doFinal(text));

    }
中间有个key排序的过程,阿里云的加密应该都是差不多的。你看看 能不能帮到你
感谢~
dxbj1016 2018-01-15
  • 打赏
  • 举报
回复
我也对接了阿里云的服务这一块,之前的写的代码你看看

Map param = new HashMap<>();
        param.put("SignatureVersion", 1.0);
        param.put("Format", "JSON");
        param.put("Timestamp", LocalDateTime.now(ZoneId.of("UTC")).format(dtf));
        param.put("RegionId", "cn-shanghai");
        param.put("AccessKeyId", accessId);
        param.put("SignatureMethod", "HMAC-SHA1");
        param.put("Version", "2014-05-15");
        param.put("LoadBalancerId", loadId);
        param.put("Action", "SetBackendServers");
        param.put("SignatureNonce", UUID.randomUUID().toString());
        param.put("BackendServers", "[{\"ServerId\":\"" + serverId + "\",\"Weight\":\"" + weight + "\"}]");

        List<String> keyList = new ArrayList(param.keySet());
        Collections.sort(keyList);

        List<String> paramList = new ArrayList<>();
        for (String key : keyList) {
            paramList.add(String.format("%s=%s", key, URLEncoder.encode(param.get(key).toString(), "UTF-8")));
        }

        String stringToSign = "GET" + "&" + URLEncoder.encode("/", "UTF-8")
                + "&" + URLEncoder.encode(StringUtils.join(paramList, "&"), "UTF-8");

        String sign = EncodeUtil.HmacSHA1AndBase64(stringToSign, securityId);

        paramList.add(String.format("%s=%s", "Signature", URLEncoder.encode(sign, "UTF-8")));


        URL url = new URL("http://slb.aliyuncs.com/?" + StringUtils.join(paramList, "&"));
使用的jdk8的时间类 private static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"); 加密的类也是网上拿过来用的,应该都是差不多的

public static String HmacSHA1AndBase64(String encryptText, String encryptKey) throws Exception {

        byte[] data=encryptKey.getBytes("UTF-8");
        //根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
        SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
        //生成一个指定 Mac 算法 的 Mac 对象
        Mac mac = Mac.getInstance("HmacSHA1");
        //用给定密钥初始化 Mac 对象
        mac.init(secretKey);

        byte[] text = encryptText.getBytes("UTF-8");
        //完成 Mac 操作
        return Base64.encodeBase64String(mac.doFinal(text));

    }
中间有个key排序的过程,阿里云的加密应该都是差不多的。你看看 能不能帮到你

81,095

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧