在我们使用第三方提供的api的时候,对方通常会提供一个
ak/sk
或者
appid/token
类似的东西才能调用他们提供的api,然后调用的时候就需要提供 nonce(随机字符串)、timestap(时间戳)、signature(签名)这些类似的参数(这三个参数多会以差不多的意思出现)。那么这三个参数分别有什么用呢?
-
timestap(时间戳)
timestap的作用是:限制时间
服务端收到请求后第一时间就会判断这次请求是否超时,判断的原理很简单,就是使用当前的时间戳和发送过来的时间戳相减,如果超出了设置的超时时间就返回请求超时,没有就进行下一步。
-
nonce(随机字符串)
nonce在调用api时的作用是 :防止重复提交
如何防止重复提交呢?服务端在用户每次使用api的时候都会将nonce缓存起来,比如使用redis缓存,用户调用一次之后将nonce缓存启动,再一次调用的时候会先去redis中查询是否存在,如果存在就返回重复提交,没有就进行下一步。
-
signature(签名)
signature的作用是:电子签名(防止篡改)
不懂电子签名的同学可以先去了解一下,signature是如何生成的呢?
这要根据官方文档提供的摘要算法进行计算一般都是sha1(sort(token、timestamp、nonce))类似。
首先我们可以根据全面商家提供的ak/sk 或者 appid/token来对重要的数据进行加密,一般商家都会提供加解密工具和示例在官方文档,然后将:加密数据、token/sk、nonce、timestap这四个项按照规定的方式排序进行签名运算最终得到电子签名。服务端最终也会通过相同的方式进行运算生成signature然后进行对比,判断是否一致。
最后
通过这个这三个参数就能够判断这次请求的在一定时间内只能使用一次这样的功能。就算别人抓包拿到请求想要篡改内容 :修改timestap或者nonce 能躲过时间限制和单次请求校验,但最终都逃不过signature的校验。
在请求一些开放平台的接口
时
,我们一般会在请求头
中
塞入一些签名相关的信息以证明身份。以微信API-V3的为例,请求头
中
包含的认证信息主要包含:
signature
(签名值)
nonce
(随机串)
timestamp
(
时
间戳)
本文将一步步介绍以上3个小玩意的含义和用途。
关键字:公钥、私钥、...
以前工作
中
写脚本访问阿里云的资源
时
,都是通过
调用
系统命令(
调用
CLI工具)的方式,这次尝试通过http请求来实现想要的操作。
本次实现
中
遇到的问题
1、想api发送请求是总是返回报错:The specified pamareter Version is not valid,从报错上看是
参数
中
设置的Version的值有问题,但反复核实请求
中
带的Version并没有问题。
解决方法:如果你遇到同样的问题,估计跟我一样,在向api发送请求是也是以
调用
系统命令curl的方式来实现的,这里要把请求的url用引号引
以前总是通过
timestamp
来防止重放攻击,但是这样并不能保证每次请求都是一次性的。今天看到了一篇文章介绍的通过
nonce
(Number used once)来保证一次有效,感觉两者结合一下,就能达到一个非常好的效果了。
重放攻击是计算机世界黑客常用的攻击方式之一,所谓重放攻击就是攻击者发...
验证用户身份最常见的方法之一是验证用户名和密码。因此,
Spring
Security为使用用户名和密码进行身份验证提供了全面的支持。
Spring
Security为从HttpServletRequest读取用户名和密码提供了三种内置机制:Form、Basic、Digest。
Form Login
Spring
Security支持通过html表单提供用户名和密码。本节详细介绍了基于表单的身份验证如何在
Spring
Security
中
工作。
让我们看看
Spring
Security
中
基于表单的登录是如何工作的
网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl
网关控制台:https://apigateway.console.aliyun.com/?spm=5176.doc42740.2.2.Q4z5ws#/cn-hangzhou/apis/list
一、如何获取错误信息
所有的 API 请求只要到达了网关,网关就会返回请求结果信息。
用户需要查看返回结果的头部,即 Header .
一、c#微信公众号开发----基本设置
参考微信官方文档
https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
开发→基本配置
公众号开发信息
注:1.记录好开发者密码,会在程序
中
验证过程
中
使用到。
2.通过appid和appsecret
调用
access_token
时
,至有在ip白名单的ip才能成功
调用
。
服务器配置
若此处开启服务器配置,设置的自动回复和自...
public class SortAndEncryptUtils {
public static String sortAndEncrypt(String appSecret, String
timestamp
, String
nonce
) {
ArrayList list = new ArrayList();
list.add(
前言:服务端与前端对接的API接口,如果被
第三方
抓包并进行恶意篡改
参数
,可能会导致数据泄露和篡改数据,下面主要围绕token,签名,
时
间戳,
三个
部分来保证API接口的安全性。
参考链接,致敬前辈:
开放API接口签名验证,让你的接口从此不再裸奔
API接口的安全设计验证:ticket,签名,
时
间戳
本文举例来说明API签名,并有具体实现流程,规则弄会,一通百通。
本文先用一个故事举例,方便理解,然后对整个流程做了逐步分析和局部代码实现,最后把代码整合起来,想直接看整合后代码的可以直接去最底。
一、故事引入签名认证原理(不要纠结为什么吃饭这么麻烦- -!)
有家饭店,只对会员开放,小明在饭店注册会员...
以下是一个使用
Java
的HttpURLConnection类生成一个POST请求的示例代码,其
中
AccessKey,sign,
timestamp
和
nonce
分别作为查询
参数
,请求头和请求体
中
的
参数
:
```
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
= generate
Nonce
();
// Generate the
signature
String sign = generate
Signature
(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 generate
Nonce
() {
// Generate a random alphanumeric string of length 16
String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuilder
nonce
Builder = new StringBuilder();
Random random = new Random();
for (int i = 0; i < 16; i++) {
int index = random.nextInt(characters.length());
char character = characters.charAt(index);
nonce
Builder.append(character);
return
nonce
Builder.toString();
private static String generate
Signature
(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
signature
Builder = new StringBuilder();
for (byte b : digest) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
signature
Builder.append('0');
signature
Builder.append(hex);
return
signature
Builder.toString();