当前位置: 首页 > news >正文

腾讯OCR签名算法

云服务器 签名方法 v3-调用方式-API 中心-腾讯云

一,签名算法-官网

copy官网

package com.smcv.customer.service.util;import org.springframework.http.HttpHeaders;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.TreeMap;public class TencentCloudAPITC3Demo {private final static Charset UTF8 = StandardCharsets.UTF_8;// 需要设置环境变量 TENCENTCLOUD_SECRET_ID,值为示例的 AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******
//    private final static String SECRET_ID = System.getenv("TENCENTCLOUD_SECRET_ID");private final static String SECRET_ID = "AKIDBE4g3B4";// 需要设置环境变量 TENCENTCLOUD_SECRET_KEY,值为示例的 Gu5t9xGARNpq86cd98joQYCN3*******
//    private final static String SECRET_KEY = System.getenv("TENCENTCLOUD_SECRET_KEY");private final static String SECRET_KEY = "tWt2uXu1uc";private final static String CT_JSON = "application/json; charset=utf-8";public static byte[] hmac256(byte[] key, String msg) throws Exception {Mac mac = Mac.getInstance("HmacSHA256");SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());mac.init(secretKeySpec);return mac.doFinal(msg.getBytes(UTF8));}public static String sha256Hex(String s) throws Exception {MessageDigest md = MessageDigest.getInstance("SHA-256");byte[] d = md.digest(s.getBytes(UTF8));return DatatypeConverter.printHexBinary(d).toLowerCase();}public static void main(String[] args) throws Exception {String service = "cvm";String host = "cvm.tencentcloudapi.com";
//        String region = "ap-guangzhou";
//        String action = "DescribeInstances";String region = "ap-shanghai";String action = "SmartStructuralOCRV2";String version = "2018-11-19";String algorithm = "TC3-HMAC-SHA256";
//        String timestamp = "1551113065";String timestamp = String.valueOf(System.currentTimeMillis() / 1000);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 注意时区,否则容易出错sdf.setTimeZone(TimeZone.getTimeZone("UTC"));String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));// ************* 步骤 1:拼接规范请求串 *************String httpRequestMethod = "POST";String canonicalUri = "/";String canonicalQueryString = "";String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + host + "\n" + "x-tc-action:" + action.toLowerCase() + "\n";String signedHeaders = "content-type;host;x-tc-action";String payload = "{\"Limit\": 1, \"Filters\": [{\"Values\": [\"\\u672a\\u547d\\u540d\"], \"Name\": \"instance-name\"}]}";String hashedRequestPayload = sha256Hex(payload);String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;System.out.println(canonicalRequest);// ************* 步骤 2:拼接待签名字符串 *************String credentialScope = date + "/" + service + "/" + "tc3_request";String hashedCanonicalRequest = sha256Hex(canonicalRequest);String stringToSign = algorithm + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;System.out.println(stringToSign);// ************* 步骤 3:计算签名 *************byte[] secretDate = hmac256(("TC3" + SECRET_KEY).getBytes(UTF8), date);byte[] secretService = hmac256(secretDate, service);byte[] secretSigning = hmac256(secretService, "tc3_request");String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();System.out.println(signature);// ************* 步骤 4:拼接 Authorization *************String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", " + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;System.out.println(authorization);TreeMap<String, String> headers = new TreeMap<String, String>();headers.put("Authorization", authorization);headers.put("Content-Type", CT_JSON);headers.put("Host", host);headers.put("X-TC-Action", action);headers.put("X-TC-Timestamp", timestamp);headers.put("X-TC-Version", version);headers.put("X-TC-Region", region);StringBuilder sb = new StringBuilder();sb.append("curl -X POST https://").append(host).append(" -H \"Authorization: ").append(authorization).append("\"").append(" -H \"Content-Type: application/json; charset=utf-8\"").append(" -H \"Host: ").append(host).append("\"").append(" -H \"X-TC-Action: ").append(action).append("\"").append(" -H \"X-TC-Timestamp: ").append(timestamp).append("\"").append(" -H \"X-TC-Version: ").append(version).append("\"").append(" -H \"X-TC-Region: ").append(region).append("\"").append(" -d '").append(payload).append("'");System.out.println(sb.toString());}public static HttpHeaders buildHeader(String payload) throws Exception {String service = "ocr";String host = "ocr.tencentcloudapi.com";String region = "ap-shanghai";String action = "SmartStructuralOCRV2";String version = "2018-11-19";String algorithm = "TC3-HMAC-SHA256";String timestamp = String.valueOf(System.currentTimeMillis() / 1000);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 注意时区,否则容易出错sdf.setTimeZone(TimeZone.getTimeZone("UTC"));String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));// ************* 步骤 1:拼接规范请求串 *************String httpRequestMethod = "POST";String canonicalUri = "/";String canonicalQueryString = "";String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + host + "\n" + "x-tc-action:" + action.toLowerCase() + "\n";String signedHeaders = "content-type;host;x-tc-action";//        String payload = "{\"Limit\": 1, \"Filters\": [{\"Values\": [\"\\u672a\\u547d\\u540d\"], \"Name\": \"instance-name\"}]}";String hashedRequestPayload = sha256Hex(payload);String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;System.out.println(canonicalRequest);// ************* 步骤 2:拼接待签名字符串 *************String credentialScope = date + "/" + service + "/" + "tc3_request";String hashedCanonicalRequest = sha256Hex(canonicalRequest);String stringToSign = algorithm + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;System.out.println(stringToSign);// ************* 步骤 3:计算签名 *************byte[] secretDate = hmac256(("TC3" + SECRET_KEY).getBytes(UTF8), date);byte[] secretService = hmac256(secretDate, service);byte[] secretSigning = hmac256(secretService, "tc3_request");String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();System.out.println(signature);// ************* 步骤 4:拼接 Authorization *************String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", " + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;System.out.println(authorization);HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.add("Authorization", authorization);httpHeaders.add("Content-Type", CT_JSON);httpHeaders.add("Host", host);httpHeaders.add("X-TC-Action", action);httpHeaders.add("X-TC-Timestamp", timestamp);httpHeaders.add("X-TC-Version", version);httpHeaders.add("X-TC-Region", region);StringBuilder sb = new StringBuilder();sb.append("curl -X POST https://").append(host).append(" -H \"Authorization: ").append(authorization).append("\"").append(" -H \"Content-Type: application/json; charset=utf-8\"").append(" -H \"Host: ").append(host).append("\"").append(" -H \"X-TC-Action: ").append(action).append("\"").append(" -H \"X-TC-Timestamp: ").append(timestamp).append("\"").append(" -H \"X-TC-Version: ").append(version).append("\"").append(" -H \"X-TC-Region: ").append(region).append("\"").append(" -d '").append(payload).append("'");System.out.println(sb.toString());return httpHeaders;}
}

调用

     HttpHeaders headers = tencentCloudAPITC3Demo.buildHeader(req);ResponseEntity<String> stringResponseEntity = restTemplateUtils.serviceApiInvoke(req, tencentOcrUrl, headers);
    public ResponseEntity<String> serviceApiInvoke(String requestBody, String url, HttpHeaders headers) {// 创建 HttpEntity 对象,用于设置请求体和请求头HttpEntity<String> httpEntity = new HttpEntity<>(requestBody, headers);// 发送 POST 请求并获取响应ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);// 输出响应结果return response;}

响应乱码问题

方案1

    public ResponseEntity<String> serviceApiInvoke(String requestBody, String url, HttpHeaders headers) {// 创建 HttpEntity 对象,用于设置请求体和请求头HttpEntity<String> httpEntity = new HttpEntity<>(requestBody, headers);List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();for (HttpMessageConverter<?> messageConverter : messageConverters) {if (messageConverter instanceof StringHttpMessageConverter) {((StringHttpMessageConverter) messageConverter).setDefaultCharset(Charset.forName("UTF-8"));}}// 发送 POST 请求并获取响应ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);// 输出响应结果return response;}

方案2

    public String serviceApiInvokeUtf8(String requestBody, String url, HttpHeaders headers) {
//        HttpHeaders httpHeaders = new HttpHeaders();// 可以设置一些参数HttpEntity httpEntity = new HttpEntity(requestBody,headers);ResponseEntity<byte[]> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, byte[].class);try {String result = new String(exchange.getBody(), "UTF-8");return result;} catch (UnsupportedEncodingException e) {e.printStackTrace();}return null;}

二,签名算法-自定义

据说也是copy官网

1,签名失败问题

背景,生产上已经跑了很长一段时间,突然有一天接口突然调不通了(什么都没动的情况下,很奇异),报错如下

2,响应报错信息

签名失败

AuthFailure.SignatureFailure

{"body": "{\"Response\":{\"Error\":{\"Code\":\"AuthFailure.SignatureFailure\",\"Message\":\"请æ±ç­¾åéªè¯å¤±è´¥ï¼è¯·æ£æ¥æ¨çç­¾å计ç®æ¯å¦æ­£ç¡®ã\"},\"RequestId\":\"ebcf25f4-ee15-4286-8366-7352414e69e4\"}}","headers": {"Date": ["Thu, 01 Aug 2024 01:29:49 GMT"],"Content-Type": ["application/json"],"Content-Length": ["195"],"Connection": ["keep-alive"]},"statusCode": 4,"statusCodeValue": 200
}

3,算法代码

package com.smcv.customer.service.util;import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;@Slf4j
public class PdfUtils {//    FailedOperation.DownLoadError	文件下载失败。
//    FailedOperation.ImageDecodeFailed	图片解码失败。
//    FailedOperation.OcrFailed	OCR识别失败。
//    FailedOperation.UnKnowError	未知错误。
//    FailedOperation.UnOpenError	服务未开通。
//    InvalidParameterValue.InvalidParameterValueLimit	参数值错误。
//    LimitExceeded.TooLargeFileError	文件内容太大。
//    ResourcesSoldOut.ChargeStatusException	计费状态异常private final static Charset UTF8 = StandardCharsets.UTF_8;// 需要设置环境变量 TENCENTCLOUD_SECRET_ID,值为示例的 AKIDz8krbsJ5**********mLPx3EXAMPLprivate final static String SECRET_ID = "";// 需要设置环境变量 TENCENTCLOUD_SECRET_KEY,值为示例的 Gu5t9xGAR***********EXAMPLEprivate final static String SECRET_KEY = "";private final static String CT_JSON = "application/json";public static byte[] hmac256(byte[] key, String msg) throws Exception {Mac mac = Mac.getInstance("HmacSHA256");SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());mac.init(secretKeySpec);return mac.doFinal(msg.getBytes(UTF8));}public static String sha256Hex(String s) throws Exception {MessageDigest md = MessageDigest.getInstance("SHA-256");byte[] d = md.digest(s.getBytes(UTF8));return DatatypeConverter.printHexBinary(d).toLowerCase();}public static HttpHeaders getTncOrc(String payload) throws Exception {String service = "ocr";String host = "ocr.tencentcloudapi.com";String region = "ap-shanghai";String action = "SmartStructuralOCRV2";String tag = "cdf41db8-29e9-11ee-9ed1-5254005e545b";String version = "2018-11-19";String algorithm = "TC3-HMAC-SHA256";String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//String timestamp = "1689760798";SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 注意时区,否则容易出错sdf.setTimeZone(TimeZone.getTimeZone("UTC"));String date = sdf.format(new Date(Long.parseLong(timestamp + "000")));// ************* 步骤 1:拼接规范请求串 *************String httpRequestMethod = "POST";String canonicalUri = "/";String canonicalQueryString = "";String canonicalHeaders = "content-type:application/json\n" + "host:" + host + "\n" + "x-tc-action:" + action.toLowerCase() + "\n";String signedHeaders = "content-type;host;x-tc-action";String hashedRequestPayload = sha256Hex(payload);String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"+ canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;// ************* 步骤 2:拼接待签名字符串 *************String credentialScope = date + "/" + service + "/" + "tc3_request";String hashedCanonicalRequest = sha256Hex(canonicalRequest);String stringToSign = algorithm + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;// ************* 步骤 3:计算签名 *************byte[] secretDate = hmac256(("TC3" + SECRET_KEY).getBytes(UTF8), date);byte[] secretService = hmac256(secretDate, service);byte[] secretSigning = hmac256(secretService, "tc3_request");String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();// ************* 步骤 4:拼接 Authorization *************String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", "+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;HttpHeaders headers = new HttpHeaders();headers.add("Authorization", authorization);headers.add("Content-Type", CT_JSON);headers.add("Host", host);headers.add("X-TC-Action", action);headers.add("X-TC-Timestamp", timestamp);headers.add("X-TC-Version", version);headers.add("X-TC-Region", region);headers.add("X-TC-Language", "zh-CN");//
//        StringBuilder sb = new StringBuilder();
//        sb.append("curl -X POST https://").append(host)
//                .append(" -H \"Authorization: ").append(authorization).append("\"")
//                .append(" -H \"Content-Type: ").append(CT_JSON).append("\"")
//                .append(" -H \"Host: ").append(host).append("\"")
//                .append(" -H \"X-TC-Action: ").append(action).append("\"")
//                .append(" -H \"X-TC-Timestamp: ").append(timestamp).append("\"")
//                .append(" -H \"X-TC-Version: ").append(version).append("\"")
//                .append(" -H \"X-TC-Region: ").append(region).append("\"")
//                .append(" -H \"X-TC-Language: ").append("zh-CN").append("\"")
//                .append(" -d '").append(payload).append("'");
//        log.info(sb.toString());return headers;}}

4,原因

对比官网签名算法,主要区别在于编码方式

处理方案:替换以下内容,接口正常了。改回老的还是签名失败(交叉对比确认,肯定是签名失败了)

private final static String CT_JSON = "application/json";
private final static String CT_JSON = "application/json; charset=utf-8";
String canonicalHeaders = "content-type:application/json\n" + "host:" + host + "\n" + "x-tc-action:" + action.toLowerCase() + "\n";
String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + host + "\n" + "x-tc-action:" + action.toLowerCase() + "\n";

5,又突然好了 

上面第四点还是用老的,不写charset=utf-8,tmd接口又正常了,why?不知道!

三,签名算法-腾讯运维提供

调用

String req = JSON.toJSONString(tncOrcReqDTO);
HashMap<String, String> authorizationHearderV3 = SingtrueUtil.getAuthorizationHearderV3(req);
String bizTokenKey = SingtrueUtil.getBizTokenKey(authorizationHearderV3, req);

算法

package com.smcv.customer.service.util;import org.springframework.http.HttpHeaders;import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;public class SingtrueUtil {private static final String TAG = "SigtrueUtil";private final static String ALGORITHM = "TC3-HMAC-SHA256"; // TC3-HMAC-SHA256:签名方法,目前固定取该值;private static final Charset UTF8 = StandardCharsets.UTF_8;private final static String CT_JSON = "application/json; charset=utf-8";private static String action = "SmartStructuralOCRV2";private static String urlStr = "https://ocr.tencentcloudapi.com";private static String service = "ocr";private static String version = "2018-11-19";private static String region = "ap-shanghai";private static String tempToken = null;private final static String host = "ocr.tencentcloudapi.com";private final static String secretId = "";private final static String secretKey = "";/*** 腾讯云签名** @param bodyParam body参数* @param service   服务名* @param secretId  secretId* @param secretKey secretKey* @param tempToken 临时证书所用的 Token ,需要结合临时密钥一起使用。临时密钥和 Token*                  需要到访问管理服务调用接口获取。长期密钥不需要 Token。* @param action    接口名称* @param version   版本号* @param region    区域* @return headers 请求头* @throws Exception e*/public static HashMap<String, String> getAuthorizationHearder(String host,String bodyParam,String service,String secretId,String secretKey,String tempToken,String action,String version,String region) throws Exception {String timestamp = String.valueOf(System.currentTimeMillis() / 1000);// 当前 UNIX 时间戳,可记录发起 API// 请求的时间。注意:如果与服务器时间相差超过5分钟,会引起签名过期错误SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 注意时区,否则容易出错sdf.setTimeZone(TimeZone.getTimeZone("UTC"));String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));// ************* 步骤 1:拼接规范请求串 *************String httpRequestMethod = "POST";String canonicalUri = "/";String canonicalQueryString = "";String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + host + "\n";String signedHeaders = "content-type;host";String hashedRequestPayload = sha256Hex(bodyParam);String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"+ canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;System.out.println(canonicalRequest);// ************* 步骤 2:拼接待签名字符串 *************String credentialScope = date + "/" + service + "/" + "tc3_request";String hashedCanonicalRequest = sha256Hex(canonicalRequest);String stringToSign = ALGORITHM + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;System.out.println(stringToSign);// ************* 步骤 3:计算签名 *************byte[] secretDate = hmac256(("TC3" + secretKey).getBytes(UTF8), date);byte[] secretService = hmac256(secretDate, service);byte[] secretSigning = hmac256(secretService, "tc3_request");String signature = bytesToHexFun(hmac256(secretSigning, stringToSign));// DatatypeConverter.printHexBinary(hmac256(secretSigning,// stringToSign)).toLowerCase();System.out.println(signature);// ************* 步骤 4:拼接 Authorization *************String authorization = ALGORITHM + " " + "Credential=" + secretId + "/" + credentialScope + ", "+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;System.out.println(authorization);HashMap<String, String> headers = new HashMap<>();if (tempToken != null && !tempToken.isEmpty()) {headers.put("X-TC-Token", tempToken);}headers.put("Authorization", authorization);headers.put("Content-Type", CT_JSON);headers.put("Host", host);headers.put("X-TC-Action", action);headers.put("X-TC-Timestamp", timestamp);headers.put("X-TC-Version", version);headers.put("X-TC-Region", region);StringBuilder sb = new StringBuilder();sb.append("curl -X POST https://").append(host).append(" -H \"Authorization: ").append(authorization).append("\"").append(" -H \"Content-Type: application/json; charset=utf-8\"").append(" -H \"Host: ").append(host).append("\"").append(" -H \"X-TC-Action: ").append(action).append("\"").append(" -H \"X-TC-Timestamp: ").append(timestamp).append("\"").append(" -H \"X-TC-Version: ").append(version).append("\"").append(" -H \"X-TC-Region: ").append(region).append("\"").append(" -d '").append(bodyParam).append("'");System.out.println(sb);return headers;}public static HashMap<String, String> getAuthorizationHearderV3(String bodyParam) throws Exception {String timestamp = String.valueOf(System.currentTimeMillis() / 1000);// 当前 UNIX 时间戳,可记录发起 API// 请求的时间。注意:如果与服务器时间相差超过5分钟,会引起签名过期错误SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 注意时区,否则容易出错sdf.setTimeZone(TimeZone.getTimeZone("UTC"));String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));// ************* 步骤 1:拼接规范请求串 *************String httpRequestMethod = "POST";String canonicalUri = "/";String canonicalQueryString = "";String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + host + "\n";String signedHeaders = "content-type;host";String hashedRequestPayload = sha256Hex(bodyParam);String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"+ canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;System.out.println(canonicalRequest);// ************* 步骤 2:拼接待签名字符串 *************String credentialScope = date + "/" + service + "/" + "tc3_request";String hashedCanonicalRequest = sha256Hex(canonicalRequest);String stringToSign = ALGORITHM + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;System.out.println(stringToSign);// ************* 步骤 3:计算签名 *************byte[] secretDate = hmac256(("TC3" + secretKey).getBytes(UTF8), date);byte[] secretService = hmac256(secretDate, service);byte[] secretSigning = hmac256(secretService, "tc3_request");String signature = bytesToHexFun(hmac256(secretSigning, stringToSign));// DatatypeConverter.printHexBinary(hmac256(secretSigning,// stringToSign)).toLowerCase();System.out.println(signature);// ************* 步骤 4:拼接 Authorization *************String authorization = ALGORITHM + " " + "Credential=" + secretId + "/" + credentialScope + ", "+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;System.out.println(authorization);HashMap<String, String> headers = new HashMap<>();if (tempToken != null && !tempToken.isEmpty()) {headers.put("X-TC-Token", tempToken);}headers.put("Authorization", authorization);headers.put("Content-Type", CT_JSON);headers.put("Host", host);headers.put("X-TC-Action", action);headers.put("X-TC-Timestamp", timestamp);headers.put("X-TC-Version", version);headers.put("X-TC-Region", region);;//		StringBuilder sb = new StringBuilder();
//		sb.append("curl -X POST https://").append(host).append(" -H \"Authorization: ").append(authorization)
//				.append("\"").append(" -H \"Content-Type: application/json; charset=utf-8\"").append(" -H \"Host: ")
//				.append(host).append("\"").append(" -H \"X-TC-Action: ").append(action).append("\"")
//				.append(" -H \"X-TC-Timestamp: ").append(timestamp).append("\"").append(" -H \"X-TC-Version: ")
//				.append(version).append("\"").append(" -H \"X-TC-Region: ").append(region).append("\"").append(" -d '")
//				.append(bodyParam).append("'");
//		System.out.println(sb);return headers;}public static HttpHeaders getAuthorizationHearderV2(String bodyParam) throws Exception {String timestamp = String.valueOf(System.currentTimeMillis() / 1000);// 当前 UNIX 时间戳,可记录发起 API// 请求的时间。注意:如果与服务器时间相差超过5分钟,会引起签名过期错误SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 注意时区,否则容易出错sdf.setTimeZone(TimeZone.getTimeZone("UTC"));String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));// ************* 步骤 1:拼接规范请求串 *************String httpRequestMethod = "POST";String canonicalUri = "/";String canonicalQueryString = "";String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + host + "\n";String signedHeaders = "content-type;host";String hashedRequestPayload = sha256Hex(bodyParam);String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"+ canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;System.out.println(canonicalRequest);// ************* 步骤 2:拼接待签名字符串 *************String credentialScope = date + "/" + service + "/" + "tc3_request";String hashedCanonicalRequest = sha256Hex(canonicalRequest);String stringToSign = ALGORITHM + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;System.out.println(stringToSign);// ************* 步骤 3:计算签名 *************byte[] secretDate = hmac256(("TC3" + secretKey).getBytes(UTF8), date);byte[] secretService = hmac256(secretDate, service);byte[] secretSigning = hmac256(secretService, "tc3_request");String signature = bytesToHexFun(hmac256(secretSigning, stringToSign));// DatatypeConverter.printHexBinary(hmac256(secretSigning,// stringToSign)).toLowerCase();System.out.println(signature);// ************* 步骤 4:拼接 Authorization *************String authorization = ALGORITHM + " " + "Credential=" + secretId + "/" + credentialScope + ", "+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;System.out.println(authorization);HttpHeaders headers = new HttpHeaders();headers.add("Authorization", authorization);headers.add("Content-Type", CT_JSON);headers.add("Host", host);headers.add("X-TC-Action", action);headers.add("X-TC-Timestamp", timestamp);headers.add("X-TC-Version", version);headers.add("X-TC-Region", region);headers.add("X-TC-Language", "zh-CN");//		StringBuilder sb = new StringBuilder();
//		sb.append("curl -X POST https://").append(host).append(" -H \"Authorization: ").append(authorization)
//				.append("\"").append(" -H \"Content-Type: application/json; charset=utf-8\"").append(" -H \"Host: ")
//				.append(host).append("\"").append(" -H \"X-TC-Action: ").append(action).append("\"")
//				.append(" -H \"X-TC-Timestamp: ").append(timestamp).append("\"").append(" -H \"X-TC-Version: ")
//				.append(version).append("\"").append(" -H \"X-TC-Region: ").append(region).append("\"").append(" -d '")
//				.append(bodyParam).append("'");
//		System.out.println(sb);return headers;}public static String getBizTokenKey(HashMap<String, String> headerMap, String bodyParam) throws IOException {String resultString;HttpURLConnection httpURLConnection = null;try {URL url = new URL(urlStr);httpURLConnection = (HttpURLConnection) url.openConnection();httpURLConnection.setConnectTimeout(6000);httpURLConnection.setUseCaches(false);// 不使用缓存httpURLConnection.setInstanceFollowRedirects(true);// 是成员变量 仅作用域当前函数,设置当前这个对象httpURLConnection.setReadTimeout(3000);httpURLConnection.setDoInput(true);httpURLConnection.setDoOutput(true);httpURLConnection.setRequestMethod("POST");for (Map.Entry<String, String> entry : headerMap.entrySet()) {httpURLConnection.setRequestProperty(entry.getKey(), entry.getValue());}// httpURLConnection.setRequestProperty();httpURLConnection.connect();// ---------------使用字节流发送数据---------------------------OutputStream out = httpURLConnection.getOutputStream();// 缓冲字节流 包装字节流BufferedOutputStream bos = new BufferedOutputStream(out);// 把字节流数组写入缓冲区中bos.write(bodyParam.getBytes("UTF-8"));// 刷新缓冲区 发送数据bos.flush();out.close();bos.close();// 如果响应码为200代表请求访问成功if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {InputStream in = httpURLConnection.getInputStream();resultString = getContent(in);} else {throw new RuntimeException("请求失败");}} catch (IOException e) {e.printStackTrace();throw new RuntimeException("请求失败");} finally {if (httpURLConnection != null) {httpURLConnection.disconnect();}}return resultString;}/*** inputStream转为String类型** @param inputStream* @return*/private static String getContent(InputStream inputStream) {BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));StringBuilder sb = new StringBuilder();String line = null;try {while ((line = bufferedReader.readLine()) != null) {sb.append(line + "/n");}} catch (IOException e) {e.printStackTrace();} finally {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}return sb.toString().replace("/n", "");}private static byte[] hmac256(byte[] key, String msg) throws Exception {Mac mac = Mac.getInstance("HmacSHA256");SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());mac.init(secretKeySpec);return mac.doFinal(msg.getBytes(UTF8));}private static String sha256Hex(String s) throws Exception {MessageDigest md = MessageDigest.getInstance("SHA-256");byte[] d = md.digest(s.getBytes(UTF8));return bytesToHexFun(d);// DatatypeConverter.printHexBinary(d).toLowerCase();}private static String bytesToHexFun(byte[] bytes) {StringBuilder buf = new StringBuilder(bytes.length * 2);for (byte b : bytes) { // 使用String的format方法进行转换buf.append(String.format("%02x", b & 0xff));}return buf.toString();}
}

相关文章:

腾讯OCR签名算法

云服务器 签名方法 v3-调用方式-API 中心-腾讯云 一&#xff0c;签名算法-官网 copy官网 package com.smcv.customer.service.util;import org.springframework.http.HttpHeaders;import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.D…...

CTFHUB-SSRF-DNS重绑定 Bypass

开启题目&#xff0c;页面空白&#xff0c;访问附件 附件是一个知乎的文章&#xff0c;翻到下面点击文中这个链接 跳转之后&#xff0c;进行设置 把得到的链接拼接到题目的后面进行访问&#xff0c;然后得到了本题的 flag...

【oracle】数据库基本使用

一、oracle数据库简介 Oracle 数据库&#xff0c;亦称 Oracle RDBMS&#xff0c;或简称 Oracle&#xff0c;是一款由甲骨文公司推出的高效、稳定且广泛应用的关系型数据库管理系统。该数据库系统不仅在数据管理领域处于领先地位&#xff0c;而且由于其良好的可移植性、易用性和…...

Action部署在线上写文章

原文&#xff1a;https://blog.c12th.cn/archives/32.html 前言 之前分别出了 Hexo 和 Hugo 的 Action搭建教程&#xff0c;相当于伪动态&#xff0c;可以在线上写文章了&#xff1b;不过对于喜欢魔改的同学就不太友好了qwq 教程 github.dev 确保在配置过程中能访问Github &…...

CC链 (Commons Collections)

目录 前置知识 CC链: https://mvnrepository.com/ CC链 CC链 Commons Collections --apache组织发布的开源库 里面主要对集合的增强以及扩展类 被广泛使用 组件,HashMap HashTable ArrayList总结CC链: 就是有反序列化入口&#xff0c;同时有cc库的情况下&#xff0c…...

左手坐标系、右手坐标系、坐标轴方向

一、右手坐标系 1、y轴朝上&#xff1a;webgl、Threejs、Unity、Unreal、Maya、3D Builder x&#xff1a;向右y&#xff1a;向上z&#xff1a;向前&#xff08;朝向观察者、指向屏幕外&#xff09; 2、z轴朝上&#xff1a;cesium、blender x&#xff1a;向右y&#xff1a;向前…...

芋道源码yudao-cloud 二开日记(商品sku数据归类为规格属性)

商品的每一条规格和属性在数据库里都是单一的一条数据&#xff0c;从数据库里查出来后&#xff0c;该怎么归类为对应的规格和属性值&#xff1f;如下图&#xff1a; 在商城模块&#xff0c;商品的单规格、多规格、单属性、多属性功能可以说是非常完整&#xff0c;如下图&#x…...

自媒体新闻资讯类网站模板/EyouCMS自媒体资讯类网站模板

自媒体新闻资讯类网站模板&#xff0c;EyouCMS自媒体资讯类网站模板。模板自带eyoucms内核&#xff0c;无需再下载eyou系统&#xff0c;原创设计、手工书写DIVCSS&#xff0c;完美兼容IE7、Firefox、Chrome、360浏览器等&#xff1b;主流浏览器&#xff1b;结构容易优化&#x…...

Python3 第六十课 -- 实例二十九

目录 一. 冒泡排序 二. 归并排序 一. 冒泡排序 冒泡排序&#xff08;Bubble Sort&#xff09;也是一种简单直观的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再…...

【JAVA入门】Day17 - GUI

【JAVA入门】Day17 - GUI 文章目录 【JAVA入门】Day17 - GUI一、组件二、事件 GUI 即图形化界面。 一、组件 一个 Java 的图形化界面项目主要用到了下面几种组件。 Java 中最外层的窗体叫做 JFrame。Java 中最上层的菜单叫做 JMenuBar。Java 中管理文字和图片的容器叫做 JLab…...

OpenAI API continuing conversation in a dialogue

题意&#xff1a;在对话中继续使用OpenAI API进行对话 问题背景&#xff1a; I am playing around with the openAI API and I am trying to continue a conversation. For example: 我正在尝试使用OpenAI API&#xff0c;并试图继续一段对话。例如&#xff1a; import open…...

6.前端怎么做一个验证码和JWT,使用mockjs模拟后端

流程图 创建一个发起请求 创建一个方法 getCaptchaImg() {this.$axios.get(/captcha).then(res > {console.log(res);this.loginForm.token res.data.data.tokenthis.captchaImg res.data.data.captchaImgconsole.log(this.captchaImg)})}, captchaImg: "", 创…...

Python酷库之旅-第三方库Pandas(064)

目录 一、用法精讲 251、pandas.Series.tz_localize方法 251-1、语法 251-2、参数 251-3、功能 251-4、返回值 251-5、说明 251-6、用法 251-6-1、数据准备 251-6-2、代码示例 251-6-3、结果输出 252、pandas.Series.at_time方法 252-1、语法 252-2、参数 252-3…...

MATLAB基础操作(二)

11.求方程2x^5-3x^371x^2-9x130的全部跟 >> p[2,0,-3,71,-9,13]; >> xroots(p); 12.求解线性方程组2x3y-z2 8x2y3z4 45x3y9z23 >> a[2,3,-1;8,2,3;45,3,9];%建立系数矩阵a >> b[2,4,23]%建立列向量b >> …...

win10 繁体简体字切换

1. 使用快捷键 Ctrl Shift F 2. 在语言设置中更改 | 点击任务栏上的“开始”按钮。 | 选择“设置”&#xff08;齿轮图标&#xff09;。 | 在弹出的“Windows 设置”窗口中&#xff0c;点击“时间和语言”。 | 选择“语言”选项。 | 在右侧找到您正在使用的输入法&#xff…...

R语言统计分析——描述性统计

参考资料&#xff1a;R语言实战【第2版】 1、整体统计 对于R语言基础安装&#xff0c;可以使用summary()函数来获取描述性统计量。summary()函数提供了最小值、最大值、四分位数、中位数和算术平均数&#xff0c;以及因子向量和逻辑向量的频数统计。 myvars<-c("mpg&…...

为什么需要合成数据进行机器学习

为什么需要合成数据进行机器学习 文章目录 一、说明二、数据缩放问题三、合成数据的前景与进展四、将合成数据与 LLM 结合使用的最佳实践五、通过合成数据释放创新 一、说明 数据是人工智能的命脉。如果没有高质量的、具有代表性的训练数据&#xff0c;我们的机器学习模型将毫无…...

传统CS网络的新生——基于2G网络的远程灌溉实现

概述&#xff1a;iphone 实现远程电话触发&#xff0c;实现灌溉绿植的一般方法 方法一&#xff1a; 远程电话触发&#xff0c;音频线左右声道会产生一个信号&#xff0c;可以在后端利用SR锁存器暂存信号&#xff0c;后级可以接相应的控制电路实现灌溉。 方法二&#xff1a; 同…...

EasyAR_稀疏空间图

EasyAR_稀疏空间图 EasyAR4.6.3 丨 Unity2020.3.15f2 1.创建稀疏空间地图 在EasyAR开发中心后台创建Scene许可证密钥&#xff0c;并且使用稀疏空间地图 2.设置稀疏空间地图库名&#xff0c;对稀疏空间地图进行管理&#xff0c;设置密钥 3.复制密钥到Unity中 添加Spatial Map Ap…...

设计模式 - Singleton pattern 单例模式

文章目录 定义单例模式的实现构成构成UML图 单例模式的六种实现懒汉式-线程不安全懒汉式-线程安全饿汉式-线程安全双重校验锁-线程安全静态内部类实现枚举实现 总结其他设计模式文章&#xff1a;最后 定义 单例模式是一种创建型设计模式&#xff0c;它用来保证一个类只有一个实…...

显示学习5(基于树莓派Pico) -- 彩色LCD的驱动

和这篇也算是姊妹篇&#xff0c;只是一个侧重SPI协议&#xff0c;一个侧重显示驱动。 总线学习3--SPI-CSDN博客 驱动来自&#xff1a;https://github.com/boochow/MicroPython-ST7735 所以这里主要还是学习。 代码Init def __init__( self, spi, aDC, aReset, aCS) :"&…...

ros vscode配置gdb调试

ros工程vscode下配置gdb的调试环境需要添加几个配置文件&#xff0c;下面贴一下用得到的几个配置文件。 c_cpp_properties.json&#xff0c;这个配置作用是方便代码跳转。 {"configurations": [{"browse": {"databaseFilename": "${defau…...

C 环境设置

C 环境设置 C语言作为一种广泛使用的编程语言,其环境设置是每个开发者必须掌握的基本技能。本文将详细介绍如何在不同的操作系统上设置C语言开发环境,包括Windows、macOS和Linux系统。我们将涵盖安装编译器、配置开发环境以及编写和运行第一个C程序。 Windows系统上的C环境…...

Linux-ubuntu操作系统装机步骤

1、下载iso镜像 方法一、访问Ubuntu官网 方法二、163镜像 2、制作U盘启动盘 方法一、UltraISO&#xff08;软碟通&#xff09;写入硬盘映像&#xff0c;参考该 [链接] 方法二、Rufus&#xff0c;参考该 [链接] 3、安装 参考该 [链接] 4、相关配置 Ubuntu 换源 参考链接…...

马尔科夫毯:信息屏障与状态独立性的守护者

马尔科夫毯&#xff08;Markov Blanket&#xff09;是概率图模型中的一个重要概念&#xff0c;用于描述某一节点在网络中的信息独立性和条件依赖关系。马尔科夫毯定义了一个节点的“信息屏障”&#xff0c;即给定马尔科夫毯中节点的状态&#xff0c;该节点与网络中其他节点的状…...

Pandas的30个高频函数使用介绍

Pandas是Python中用于数据分析的一个强大的库&#xff0c;它提供了许多功能丰富的函数。本文介绍其中高频使用的30个函数。 read_csv(): 从CSV文件中读取数据并创建DataFrame对象。 import pandas as pd df pd.read_csv(data.csv) read_excel(): 从Excel文件中读取数据…...

1. protobuf学习

文章目录 1. protobuf介绍1.1 ProtoBuf使用场景说明2. 其他序列化介绍2.1 Json2.1.1 使用Json序列化2.1.2 Json反序列化2.2 其他可选地序列化和反序列化3. protoBuf3.1 protobuf数据类型3.2 protobuf使用步骤3.2.1 定义proto文件3.2.2 编译proto文件3.2.2.1 安装protocol buffe…...

Java面试题:SpringBean的生命周期

SpringBean的生命周期 BeanDefinition Spring容器在进行实例化时,会将xml配置的信息封装成BeanDefinition对象 Spring根据BeanDefinition来创建Bean对象 包含很多属性来描述Bean 包括 beanClassName:bean的类名,通过类名进行反射 initMethodName:初始化方法名称 proper…...

50 IRF检测MAD-BFD

IRF 检测MAD-BFD IRF配置思路 网络括谱图 主 Ten-GigabitEthernet 1/0/49 Ten-GigabitEthernet 1/0/50 Ten-GigabitEthernet 1/0/51 备 Ten-GigabitEthernet 2/0/49 Ten-GigabitEthernet 2/0/50 Ten-GigabitEthernet 2/0/51 1 利用console线进入设备的命令行页…...

SpringSecurity-1(认证和授权+SpringSecurity入门案例+自定义认证+数据库认证)

SpringSecurity 1 初识权限管理1.1 权限管理的概念1.2 权限管理的三个对象1.3 什么是SpringSecurity 2 SpringSecurity第一个入门程序2.1 SpringSecurity需要的依赖2.2 创建web工程2.2.1 使用maven构建web项目2.2.2 配置web.xml2.2.3 创建springSecurity.xml2.2.4 加载springSe…...

梅州网站建设wlwl/站长工具日本

IOS环境搭建与开发入门 (此博文图片显示不了&#xff0c;请下载图文教程http://download.csdn.net/detail/jingwen3699/4424117) 一、注册APPLE ID 1.在苹果官网上下载iTunes。 官方下载地址&#xff1a;http://www.apple.com/itunes/download/ 2.安装iTunes. 3.启动iTunes…...

减肥网站开发目的/无锡百度快照优化排名

在i386文件夹里有一个eula.txt&#xff0c;最后有一行EULAID&#xff0c;就是你的版本 OEM:WX.2_PRO_OEM_TW(or.WX.2_PRE_OEM_TW) EVAL:WX.2_PRO_RVL_TW(or.WX.2_PRE_RAL_TW) RTL.:WX.4_PRO_RTL_TW中文正式版的版本是EULAID:WX.4_PRO_RTL_CN 1.如果是WX.开头是正式版&#xff0…...

h5网站源代码/自己如何做网站

本文转载自一位做前端开发的朋友的博客【岁月如歌】&#xff0c;他向学习JavaScript的朋友推荐了很多非常不错的书籍及在线教程&#xff0c;适合英语能力不错的朋友参阅&#xff0c;转载如下&#xff1a; 最近 reddit 有讨论&#xff1a;References for JavaScript Mastery. 去…...

淘宝内部卷怎么做网站/特色产品推广方案

ChartDirector是一个非常理想的图表工具&#xff0c;它拥有广泛的图表类型、分层架构、实时互动的大数据表、普遍适应于各种应用程序以及支持PDF和SVG图标等的优点。此系列连载旨在介绍ChartDirector的实用教程&#xff0c;供大家学习讨论。一、简单条形图&#xff08;一&#…...

北京的广告公司网站建设/网站关键词快速排名技术

在搭建opencms之前我们需要先搭建好tomcat。Mysql数据库先安装 jdk&#xff0c;下载好jdk和apache-tomcat这两个软件包。(1)安装jdk过程中先解压该压缩包 命令&#xff1a;tar –zxvf jdk –C/usr/local(jdk安装路径)(2)然后需要在环境变量文件中添加exportJAVA_HOME/usr/loc…...

免费手机做网站/seo是免费的吗

放假几天回来&#xff0c;svn罢工了&#xff0c;加上我一直在两个地方同时操作svn&#xff0c;SVN——Previous operation has not finished;run ‘cleanup’ if it was interupted。 反正就是你一更新版本&#xff0c;就让你clean up &#xff0c;一clean up 就报上述错误&…...