第三方调用时 Nonce TimeStamp Signature 这三个参数有什么用?

Timestamp用于防止请求超时,Nonce避免重复提交,Signature确保数据完整性。通过时间戳检查时效性,随机字符串nonce防止重放攻击,签名则通过特定算法确保内容未被篡改。这些机制增强了API的安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第三方调用时TimeStamp Nonce Signature 这三个参数有什么用?

在我们使用第三方提供的api的时候,对方通常会提供一个ak/sk或者 appid/token类似的东西才能调用他们提供的api,然后调用的时候就需要提供 nonce(随机字符串)、timestap(时间戳)、signature(签名)这些类似的参数(这三个参数多会以差不多的意思出现)。那么这三个参数分别有什么用呢?

  1. timestap(时间戳)
    timestap的作用是:限制时间
    服务端收到请求后第一时间就会判断这次请求是否超时,判断的原理很简单,就是使用当前的时间戳和发送过来的时间戳相减,如果超出了设置的超时时间就返回请求超时,没有就进行下一步。
  2. nonce(随机字符串)
    nonce在调用api时的作用是 :防止重复提交
    如何防止重复提交呢?服务端在用户每次使用api的时候都会将nonce缓存起来,比如使用redis缓存,用户调用一次之后将nonce缓存启动,再一次调用的时候会先去redis中查询是否存在,如果存在就返回重复提交,没有就进行下一步。
  3. signature(签名)
    signature的作用是:电子签名(防止篡改)
    不懂电子签名的同学可以先去了解一下,signature是如何生成的呢?
    这要根据官方文档提供的摘要算法进行计算一般都是sha1(sort(token、timestamp、nonce))类似。
    首先我们可以根据全面商家提供的ak/sk 或者 appid/token来对重要的数据进行加密,一般商家都会提供加解密工具和示例在官方文档,然后将:加密数据、token/sk、nonce、timestap这四个项按照规定的方式排序进行签名运算最终得到电子签名。服务端最终也会通过相同的方式进行运算生成signature然后进行对比,判断是否一致。
    最后
    通过这个这三个参数就能够判断这次请求的在一定时间内只能使用一次这样的功能。就算别人抓包拿到请求想要篡改内容 :修改timestap或者nonce 能躲过时间限制和单次请求校验,但最终都逃不过signature的校验。
以下是一个使用Java的HttpURLConnection类生成一个POST请求的示例代码,其中AccessKey,sign,timestampnonce分别作为查询参数,请求头和请求体中的参数: ```java import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import java.util.Random; public class ExamplePostRequest { private static final String ACCESS_KEY = "your_access_key_here"; private static final String SECRET_KEY = "your_secret_key_here"; private static final String BASE_URL = "http://example.com/api/post"; public static void main(String[] args) throws Exception { String requestBody = "{\"key1\":\"value1\",\"key2\":\"value2\"}"; String hsPartyId = "your_hsparty_id_here"; String timestamp = Long.toString(System.currentTimeMillis() / 1000L); String nonce = generateNonce(); // Generate the signature String sign = generateSignature(hsPartyId, timestamp, nonce, requestBody); // Build the query string String queryString = String.format("AccessKey=%s&sign=%s&timestamp=%s&nonce=%s", ACCESS_KEY, sign, timestamp, nonce); // Build the request URL String requestUrl = String.format("%s?%s", BASE_URL, queryString); // Build the request headers Map<String, String> headers = new HashMap<>(); headers.put("hsPartyId", hsPartyId); // Send the POST request String response = sendPostRequest(requestUrl, headers, requestBody); // Print the response System.out.println(response); } private static String sendPostRequest(String requestUrl, Map<String, String> headers, String requestBody) throws Exception { URL url = new URL(requestUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // Set HTTP method to POST connection.setRequestMethod("POST"); // Set request headers for (Map.Entry<String, String> entry : headers.entrySet()) { connection.setRequestProperty(entry.getKey(), entry.getValue()); } // Set content type and length connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Content-Length", Integer.toString(requestBody.getBytes().length)); // Enable output and input connection.setDoOutput(true); connection.setDoInput(true); // Send request body DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); outputStream.writeBytes(requestBody); outputStream.flush(); outputStream.close(); // Read response BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder responseBuilder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { responseBuilder.append(line); } reader.close(); return responseBuilder.toString(); } private static String generateNonce() { // Generate a random alphanumeric string of length 16 String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; StringBuilder nonceBuilder = new StringBuilder(); Random random = new Random(); for (int i = 0; i < 16; i++) { int index = random.nextInt(characters.length()); char character = characters.charAt(index); nonceBuilder.append(character); } return nonceBuilder.toString(); } private static String generateSignature(String hsPartyId, String timestamp, String nonce, String requestBody) throws NoSuchAlgorithmException { // Concatenate the hsPartyId, timestamp, nonce, and requestBody String concatenatedString = hsPartyId + timestamp + nonce + requestBody; // Generate the SHA-256 hash of the concatenated string using the secret key MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(concatenatedString.getBytes()); messageDigest.update(SECRET_KEY.getBytes()); byte[] digest = messageDigest.digest(); // Convert the hash to a hexadecimal string StringBuilder signatureBuilder = new StringBuilder(); for (byte b : digest) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) { signatureBuilder.append('0'); } signatureBuilder.append(hex); } return signatureBuilder.toString(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值