接口调用AK/SK常用验证方式,保证请求合法性

摘要:本文主要介绍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),然后再次签名验证参数是否正确。
相关推荐
泡海椒11 分钟前
jquick-pdf 柱状图(JBar)实战:Java 生成政务项目审批数量趋势 PDF
后端
灿飞22 分钟前
Kotlin与Java虚拟机十一:类与属性:构造顺序、backing field 与显式 backing field
java·后端·kotlin
终码一生23 分钟前
IntelliJ IDEA 2026.3 发布:智能体住进 IDE
后端
Gopher_HBo24 分钟前
profbuf.go —— 单写单读无锁环形缓冲
后端
Oracle恢复实录1 小时前
YashanDB → Oracle DBLink:PL/SQL 变量日期条件未下推
后端
橙序员小站1 小时前
插件发布3天,下载破千:我把公众号创作接进了DSH
后端
用户298698530141 小时前
Python 实战:把代码写入 Word 文档的两种实现方式
后端·python·api
挖掘狂人2 小时前
六条分支,一条主干:我的 Git 分支管理心得
git·后端·程序员
程序员cxuan2 小时前
再见了 Typora
人工智能·后端·程序员
Rain的Java大神之路2 小时前
你背的Spring答案,全是5.x时代的:7.0.8源码一翻,80%的博客都过时了
java·后端·面试