对外接口验证sign工具

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 对外接口验证sign工具

public class SignUtils {


    /**
     * 对外接口验证
     * @param app_id
     * @param my_app_id
     * @param my_app_secret
     * @param app_secret
     * @param timestamp
     * @param sign
     * @return
     */
    public boolean sign(String app_id,String my_app_id,String app_secret,String my_app_secret,
                        Long timestamp,String sign,String my_sign){
        boolean signBool = false;
        boolean ids = my_app_id.equals(app_id);
        boolean secret = my_app_secret.equals(app_secret);
        boolean timeSign = false;
        int timeAbs = equalsTimeMin(timestamp);
        if(timeAbs<=5){
            timeSign = true;
        }else{
            timeSign = false;
        }

        Encodes encodes = new Encodes();
        MD5Tools md5Tools = new MD5Tools();
        String md5Sign = md5Tools.MD5(my_sign).toUpperCase();
        boolean isSign = sign.equals(md5Sign);

        if(ids==true&&secret==true&&timeSign==true&&isSign==true){
            signBool = true;
        }else{
            signBool = false;
        }
        return signBool;
    }


    /**
     * 比较两个时间戳相差多少分钟
     */
    public int equalsTimeMin(long timestamp){
        if("".equals(timestamp)){
            return 10000000;
        }
        long time = (System.currentTimeMillis() - timestamp) / (1000 * 60);
        int timeInt = (int)time;
        int timeAbs = Math.abs(timeInt);
        return timeAbs;
    }

}






import java.security.MessageDigest;

/**
 * MD5加密工具类
 * <功能详细描述>
 *
 * @author  chenlujun
 * @version  [版本号, 2014年10月1日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class MD5Tools
{
    public final static String MD5(String pwd) {
        //用于加密的字符
        char[] md5String = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'A', 'B', 'C', 'D', 'E', 'F'};
        try {
            //使用平台的默认字符集将此 String 编码为 byte序列,并将结果存储到一个新的 byte数组中
            byte[] btInput = pwd.getBytes();

            //信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。
            MessageDigest mdInst = MessageDigest.getInstance("MD5");

            //MessageDigest对象通过使用 update方法处理数据, 使用指定的byte数组更新摘要
            mdInst.update(btInput);

            // 摘要更新之后,通过调用digest()执行哈希计算,获得密文
            byte[] md = mdInst.digest();

            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char[] str = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {   //  i = 0
                byte byte0 = md[i];  //95
                str[k++] = md5String[byte0 >>> 4 & 0xf];    //    5
                str[k++] = md5String[byte0 & 0xf];   //   F
            }

            //返回经过加密后的字符串
            return new String(str);

        } catch (Exception e) {
            return null;
        }
    }
}

验签规则:

一、 验签规则

1. 概述

接口出于安全考虑,需要进行签名校验。客户需要生成一对密钥,私钥用于加签,自行 保管,公钥用于验签,提供给奥烱。涉及验签的接口,增加时间戳,为避免重放攻击。

2. 准备工作

客户需要生成 SHA256withRSA 2048 密钥,可以使用 openssl 工具生成。 首先在终端中进入 openssl 工具,依次执行如下命令(复制运行时请不要复制 OpenSSL> 提示符及 注释)

OpenSSL> genrsa -out app_private_key.pem 2048 #生成私钥 
OpenSSL> pkcs8 -topk8 -inform PEM -in app_private_key.pem -outform PEM - nocrypt -out app_private_key_pkcs8.pem #Java 开发者需要将私钥转换成 PKCS8 格式 
OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem #生成公钥 
OpenSSL> exit #退出 O penSSL 程序

得到三个文件:

1:app_private_key.pem : 开发者 RSA 私钥,非 Java 语言适用请自行妥善保管。 2:app_private_key_pkcs8.pem : pkcs8 格式开发者 RSA 私钥,(Java 语言适用)请自行 妥善保管。 3:app_public_key.pem : 开发者 RSA 公钥,提供给奥烱方面,验签使用

3. 验签步骤

将请求的参数名进行字典升序排列,把参数名和参数值直接拼接起来,对拼接形成的字符串 +自己的私钥 调用 rsa 签名算法(SHA256WithRSA)生成 sign 值。

签名生成的具体步骤为:

1、准备自己保留的 rsa 私钥;
2、对请求参数进行字典升序排列 ;
3、以&拼接排好序的参数,参数的形式为 key=value(key 和 value 去除首尾空格);

4、计算步骤 3 生成结果+自己的私钥 调用 rsa 签名算法(SHA256WithRSA)生成 sign 值

注:

1、签名时的所有参数,无须 urlencode;

2、编码统一使用 UTF-8;

3、key 和 value 的首尾请不要有空格,不然容易出现签名错误。

4、rsa 签名算法:SHA256WithRSA 加密前的明文最大长度 247 字节,解密密文最大长 度为 256 字,秘钥长度为 2048

5、对于不传值的字段或传值为空串的字段均不参与签名计算

示例 1: token 生成接口的 sign 参数生成示例

1.准备自己保留的 rsa 私钥;

2. 对请求参数的 key(参数名)进行字典升序排列。排好序的参数信息依次为:

appSecret:16498a942123

appId:164989231421

timestamp:1602664027823

以&拼接排好序的参数,参数的形式为 key=value。拼接结果为:

aoyiProductInventoryRequest={“appId”:“164989231421”,“appSecret”:“1649 8a942123”,“divisionCode”:“812”,“itemId”:“30506745”,“num”:1,“skuId”:“3 0508566001”,“timestamp”:1602664027823}&appId=164989231421&appSecret=1 6498a942123&timestamp=1602664027823

4、计算步骤 3 生成结果 data +自己的私钥 privateKey 调用 rsa 签名函数生成 sign 值 有加密增加验签 生成签名如下: QMpBtudcsVppihkZpwkYqEy7/+eWt8wUyPRm1Xn/lnUbcR/SFNQm67FW2PmYyYITko3ee HxEVqT6WjqPDVT2/1wQRG7QR/zT6gbXVbce6oj2h6rNmjhMwNT3jm3O9PzgOnLUX0+Y3K Dvenf4YEn1CqhZQOGwTJJx5jrGsw4HnXuSjSFG78K/5kTXyZAnHE0fdTWFGmWTltvMKIu sxCuchK2ceWNey2bd6cVOFmKkAofqfCn0BSBpxqFvvq3HtnZ49EVj8E3o0Yku9AonM2Cn kf3tzp8XsqvlSO6QoVukPQyAELH3J9iidTgZBt2lP45PaMHKsOxxnGn1CFqEcpsWSQ==

appId与 appSecret生成

package org.aoyi.common.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.UUID;

/**
 * @Auther: Steven
 * @Date: 2022/1/5 15:55
 * @Description:
 */
public class AppUtils {
    //生成 app_secret 密钥
    private final static String SERVER_NAME = "mazhq_abc123";
    private final static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
            "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
            "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
            "W", "X", "Y", "Z"};

    /**
     * @Description: <p>
     * 短8位UUID思想其实借鉴微博短域名的生成方式,但是其重复概率过高,而且每次生成4个,需要随即选取一个。
     * 本算法利用62个可打印字符,通过随机生成32位UUID,由于UUID都为十六进制,所以将UUID分成8组,每4个为一组,然后通过模62操作,结果作为索引取出字符,
     * 这样重复率大大降低。
     * 经测试,在生成一千万个数据也没有出现重复,完全满足大部分需求。
     * </p>
     */
    public static String getAppId() {
        StringBuffer shortBuffer = new StringBuffer();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        for (int i = 0; i < 8; i++) {
            String str = uuid.substring(i * 4, i * 4 + 4);
            int x = Integer.parseInt(str, 16);
            shortBuffer.append(chars[x % 0x3E]);
        }
        return shortBuffer.toString();

    }

    /**
     * <p>
     * 通过appId和内置关键词生成APP Secret
     * </P>
     */
    public static String getAppSecret(String appId) {
        try {
            String[] array = new String[]{appId, SERVER_NAME};
            StringBuffer sb = new StringBuffer();
            // 字符串排序
            Arrays.sort(array);
            for (int i = 0; i < array.length; i++) {
                sb.append(array[i]);
            }
            String str = sb.toString();
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(str.getBytes());
            byte[] digest = md.digest();

            StringBuffer hexstr = new StringBuffer();
            String shaHex = "";
            for (int i = 0; i < digest.length; i++) {
                shaHex = Integer.toHexString(digest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexstr.append(0);
                }
                hexstr.append(shaHex);
            }
            return hexstr.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    public static void main(String[] args) {
        String appId = getAppId();
        String appSecret = getAppSecret(appId);
        System.out.println("appId: "+appId);
        System.out.println("appSecret: "+appSecret);
    }
}


相关文章
|
3月前
|
IDE 测试技术 API
使用京东API接口适用于的环境及验证调用合法性的方法
在电商领域,京东API接口支持商品信息查询、订单处理等功能。开发者需确保在稳定服务器端环境使用,选择合适编程语言及框架,并具备足够网络带宽处理能力。开发环境应配备IDE或代码编辑器及所需库。测试环境需充分验证API稳定性与可靠性。合法性验证包括:正确使用App Key和App Secret进行鉴权;掌握签名规则并在请求中添加签名;遵守请求频率限制;理解并遵循数据使用协议。遵循这些指导原则可保证API调用的合法性和稳定性。
|
3月前
|
API
【Azure 应用服务】在App Service中调用外部服务API时需要携带客户端证书,而多次调用的情况下会出现WindowsCryptographicException Keyset does not exist异常
【Azure 应用服务】在App Service中调用外部服务API时需要携带客户端证书,而多次调用的情况下会出现WindowsCryptographicException Keyset does not exist异常
|
4月前
|
安全 API 网络安全
​邮箱OTP认证验证API发送邮件接口
**摘要 (Markdown格式):** OTP认证增强在线服务安全,尤其适用于邮箱验证。AOKSend提供邮箱OTP验证API,实现安全的邮件发送和用户身份验证。关键优势包括提高安全性、简化用户体验、实时发送、可扩展性和多层安全。配置涉及生成API密钥、设置SMTP、实现OTP逻辑、发送邮件及验证。AOKSend的分析工具帮助优化策略,适合各规模企业。
|
4月前
|
移动开发 JavaScript
thinkPHP5.0开发微信H5页面分享接口signature验证失败,signature与微信 JS 接口签名校验工具返回结果不一致
thinkPHP5.0开发微信H5页面分享接口signature验证失败,signature与微信 JS 接口签名校验工具返回结果不一致
86 0
|
6月前
|
数据采集 存储 安全
数据功能验证
数据功能验证
108 4
|
6月前
|
JSON 前端开发 生物认证
REST API 的指纹验证机制
REST API 的指纹验证机制
77 0
|
11月前
|
缓存 安全 NoSQL
App开放接口api安全:Token签名sign的设计与实现
在app开放接口api的设计中,避免不了的就是安全性问题,因为大多数接口涉及到用户的个人信息以及一些敏感的数据,所以对这些 接口需要进行身份的认证,那么这就需要用户提供一些信息,比如用户名密码等,但是为了安全起见让用户暴露的明文密码次数越少越好,我们一般在web项目 中,大多数采用保存的session中,然后在存一份到cookie中,来保持用户的回话有效性。
|
算法 Linux 网络安全
设备端mqtt sign(签名)原理以及实践示例
设备端mqtt sign(签名)原理以及实践示例
设备端mqtt sign(签名)原理以及实践示例
|
安全 JavaScript 前端开发
OAuth2的定义和运行流程
开放授权(Open Authorization OAuth) 是一种资源提供商用于授权第三方应用代表资源所有者获取有限访问权限的授权机制。由于在整个授权过程中,第三方应用都无法触及用户的密码就可以获取部分资源的使用权限,所以OAuth是开放安全的。
OAuth2的定义和运行流程
|
存储 算法 测试技术
接口测试平台代码实现156:私有client证书设置
接口测试平台代码实现156:私有client证书设置
接口测试平台代码实现156:私有client证书设置