阿里云视频直播API签名机制源码
2021-06-30 13:04
标签:keyset base sim init url 源码 random net 公有 阿里云视频直播签名机制,官方文档链接:https://help.aliyun.com/document_detail/50286.html?spm=a2c4g.11186623.2.11.2a053653zSTuUw#concept-50286-zh 您在访问时,需要按照下面的方法对请求进行签名处理。 对于字符 A~Z、a~z、0~9 以及字符“-”、“_”、“.”、“~”不编码; 对于其它字符编码成 对于扩展的 UTF-8 字符,编码成 英文空格( )要编码成 该编码方式和一般采用的 1-https://blog.csdn.net/u010904352/article/details/53737625 阿里云视频直播API签名机制源码 标签:keyset base sim init url 源码 random net 公有 原文地址:https://www.cnblogs.com/wobuchifanqie/p/9981291.html阿里云视频直播API签名机制源码
本文展示:通过代码实现下阿里视频直播签名处理规则
官方文档说明如下:
Signature
参数)进行排序。
%XY
的格式,其中 XY
是字符对应 ASCII 码的 16 进制表示。比如英文的双引号(”)对 应的编码为 %22
;%XY%ZA…
的格式;%20
,而不是加号(+)。application/x-www-form-urlencoded
MIME 格式编码算法(比如 Java 标准库中的 java.net.URLEncoder
的实现)相似,但又有所不同。实现时,可以先用标准库的方式进行编码,然后把编码后的字符串中加号(+)替换成 %20
、星号(*)替换成 %2A
、%7E
替换回波浪号(~),即可得到上述规则描述的编码字符串。这个算法可以用下面的 percentEncode 方法来实现:private static final String ENCODING = "UTF-8";
private static String percentEncode(String value) throws UnsupportedEncodingException {
return value != null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
}
StringToSign=
HTTPMethod + “&” +
percentEncode(“/”) + ”&” +
percentEncode(CanonicalizedQueryString)
HTTPMethod
是提交请求用的 HTTP 方法,比如 GET。percentEncode(“/”)
是按照步骤 1.ii 中描述的 URL 编码规则对字符 “/” 进行编码得到的值,即 %2F。percentEncode(CanonicalizedQueryString)
是对步骤 1 中构造的规范化请求字符串按步骤 1.ii 中描述的 URL 编码规则编码后得到的字符串。
根据官方文档,源码实现如下:
package com.hs.common.alilive;
import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
public class AliLiveSignatureUtil {
public static final String Format = "JSON";
public static final String VERSION = "2016-11-01";
public static final String AccessKeyId = "testkey";//填写你的key
public static final String AccessKeySecret = "testsecret";//填写你的Secret
// public static final String Signature = "";
public static final String SignatureMethod = "HMAC-SHA1";
// public static final String Timestamp = getUTCTimeStr();
public static final String SignatureVersion = "1.0";
// public static final String SignatureNonce = RandomStringUtils.randomAlphanumeric(12);
private static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd‘T‘HH:mm:ss‘Z‘";
//1-根据请求参数Map获取签名
public static String getSignatureFromParam(Map
String signature = "";
try {
final String SEPARATOR = "&";
//1-获取请求参数构造规范化的请求字符串(Canonicalized Query String)
//1-1-对参数进行排序
String[] sortedKeys = (String[]) paramMap.keySet().toArray(new String[]{});
Arrays.sort(sortedKeys);
//1-2-参数编码、参数名称和值用英文等号(=)进行连接、使用“&”符号连接,即得到规范化请求字符串,
//这里将参数编码、英文等号(=)连接、使用“&”符号连接三步一起放在循环里面进行操作
StringBuilder canonicalizedQueryString = new StringBuilder();
for (String key : sortedKeys) {
canonicalizedQueryString.append("&").append(percentEncode(key))
.append("=").append(percentEncode((String) paramMap.get(key)));
}
//2-将上一步构造的规范化字符串按照下面的规则构造成待签名的字符串(注意percentEncode的使用)。
//HTTPMethod 是提交请求用的 HTTP 方法,比如 GET。
//percentEncode(“/”) 是按照步骤 1.ii 中描述的 URL 编码规则对字符 “/” 进行编码得到的值,即 %2F。
//percentEncode(CanonicalizedQueryString) 是对步骤 1 中构造的规范化请求字符串按步骤 1.ii 中描述的 URL 编码规则编码后得到的字符串。
StringBuilder stringToSign = new StringBuilder();
stringToSign.append("GET").append(SEPARATOR).append(percentEncode("/")).append(SEPARATOR);
stringToSign.append(percentEncode(canonicalizedQueryString.toString()
.substring(1)));
System.out.println(stringToSign);
//3- 按照 RFC2104 的定义,计算待签名字符串 StringToSign 的 HMAC 值。
//计算签名时使用的 Key 就是您持有的 Access Key Secret 并加上一个 “&” 字符(ASCII:38),使用的哈希算法是 SHA1。()
//final String ALGORITHM = "HMAC-SHA1";//注意使用HMAC-SHA1会报错,要用HmacSHA1(但是我看的参考博客用的是“HMAC-SHA1”)
final String ALGORITHM = "HmacSHA1";
final String ENCODING = "UTF-8";
String key = AccessKeySecret + "&";
Mac mac = Mac.getInstance(ALGORITHM);
mac.init(new SecretKeySpec(key.getBytes(ENCODING), ALGORITHM));
byte[] signData = mac.doFinal(stringToSign.toString().getBytes(ENCODING));
//4-按照 Base64 编码规则把上面的 HMAC 值编码成字符串,即得到签名值(Signature)。
signature = new String(new BASE64Encoder().encode(signData));
signature = percentEncode(signature);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
return signature;
}
//1-1-转码
private static String percentEncode(String value) throws UnsupportedEncodingException {
return value != null ? URLEncoder.encode(value, "utf-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
}
//1-2-获取时间
private static String getUTCTimeStr() {
//1、取得本地时间:
final Calendar cal = Calendar.getInstance();
System.out.println(cal.getTime());
//2、取得时间偏移量:
final int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
System.out.println(zoneOffset);
//3、取得夏令时差:
final int dstOffset = cal.get(Calendar.DST_OFFSET);
System.out.println(dstOffset);
//4、从本地时间里扣除这些差量,即可以取得UTC时间:
cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
return df.format(cal.getTime());
}
}
参考资料:
上一篇:js的内联和外部调用
下一篇:api