对外接口验证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×tamp=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);
}
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggiheg
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13