摘要:本文主要介绍api
接口调用常见的加密方式ak/sk
,这种方式对于非敏感数据传输的接口做调用签名认证是非常有效的,效率高比较高,下面给出几个工具类和使用案例。
AkSkGenerator
秘钥对生成
java
/**
* ak sk 生成器
* @author huzhihui
* @version $ v 0.1 2025/1/21 8:58 Exp $$
*/
public class AkSkGenerator {
private static final int KEY_LENGTH = 32;
/**
* 生成ak/sk
* @return
*/
public static AkSk generate(){
AkSk akSk = new AkSk();
akSk.setAccessKey(generateKey());
akSk.setSecretKey(generateKey());
return akSk;
}
/**
* 生成key
* @return
*/
private static String generateKey() {
SecureRandom secureRandom = new SecureRandom();
byte[] randomBytes = new byte[KEY_LENGTH];
secureRandom.nextBytes(randomBytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes);
}
@Data
public static class AkSk {
/** */
private String accessKey;
/** */
private String secretKey;
}
}
AkSkSignatureUtil
签名工具类
java
public class AkSkSignatureUtil {
/**
* 生成签名
* @param secretKey
* @param params
* @return
* @throws Exception
*/
public static String generateSignature(String secretKey, Long timestamp, Map<String, String> params) throws Exception {
// 使用 TreeMap 对参数进行排序
Map<String, String> sortedParams = new TreeMap<>(params);
sortedParams.put("timestamp", timestamp.toString());
// 构建待签名字符串
StringBuilder dataToSign = new StringBuilder();
for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
dataToSign.append(entry.getKey()).append(entry.getValue());
}
// 生成签名
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
mac.init(secretKeySpec);
byte[] hmacData = mac.doFinal(dataToSign.toString().getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(hmacData);
}
}
使用案例
生成密钥对
ak
是用于网络传输,sk
只能调用方和服务器方才能知道,需要妥善保管。
java
private static AkSkGenerator.AkSk aksk(){
AkSkGenerator.AkSk akSk = AkSkGenerator.generate();
System.out.println("ak:" + akSk.getAccessKey());
System.out.println("sk:" + akSk.getSecretKey());
System.out.println(System.currentTimeMillis());
return akSk;
}
生成签名
下面的案例用于展示签名过程,实际的调用我给出伪代码图。
java
private static void generateSignature() throws Exception{
Map<String, String> paramMap = new HashMap<>();
paramMap.put("username", "张三");
paramMap.put("age", "12");
paramMap.put("address", "中国");
String signature = AkSkSignatureUtil.generateSignature("s4RA20ZmpIt4eXasKztcX-aKAOyxlmICzWUTbcIKqCw", 1737424189619L, paramMap);
System.out.println(signature);
}
实际生产过程中使用方式
- 接口请求方式
POST
- 参数定义,一般两种方式
@RequestBody
接收参数
参数定义 | 描述 |
---|---|
ak | 请求的key |
timestamp | 时间戳 |
data | 传输的对象 |
String data
来接收json
字符串
data
参数转map
,如果是字符串,直接转就行了,但是如果是对象,则需要把对象里面的属性转map
,使用BeanUtil.beanToMap(xxx)
,然后再次签名验证参数是否正确。