首页 > 编程语言 >php+java加密对接算法

php+java加密对接算法

时间:2024-03-08 15:37:16浏览次数:26  
标签:util 加密 String java return import dto php

请求示例:

{
  "appKey": "demo",
  "nonce": "12345",
  "sign": "04a8ba0a19ffc491716131a542729a9c250d84ce4211889a15f920ce974cf23b",
  "signType": "HmacSHA256",
  "timestamp": 1663998514
}
JSON

Sign生成方式

  1. 拼接参数:signType=?&appKey=?&appSecret=?&nonce=?&timestamp=? 如:signType=HmacSHA256&appKey=demo&appSecret=demo&nonce=12345&timestamp=1663998514。

注意:需要将appSecret设置入签名拼接参数

  1. 字符串转大写 SIGNTYPE=HMACSHA256&APPKEY=DEMO&APPSECRET=DEMO&NONCE=12345&TIMESTAMP=1663998514
  2. 字符串中的字符升序排序前:SIGNTYPE=HMACSHA256&APPKEY=DEMO&APPSECRET=DEMO&NONCE=12345&TIMESTAMP=1663998514
  3. 按字符排序:&&&&111223344555666899=====AAAAACCCDDEEEEEEEEGHHIIKMMMMMNNNOOOPPPPPPRSSSSTTTTYY
  4. HmacMD5或者HmacSHA256加密生成签名,利用秘钥和所需的加密签名算法对上述字符串进行加密成密文,作为sign签名字符串一并发送到请求接口;
  5. 将获取到sign字符串设置进参数即可。

php代码

        $nonce =  rand(100000, 999999);//随机数,可以根据需要自己写函数实现
        $timestamp = time();
        $appKey = 'demo';
        $appSecret = 'demo';
        $params = [
            'appKey' => $appKey,//$appKey,
            'nonce' => $nonce,//$nonce,
            'signType' => 'HmacSHA256',
            'timestamp' => $timestamp,//$timestamp
        ];
        $tempParams = $params;
        $tempParams['appSecret'] = $appSecret;
        $httpBuidParams = http_build_query($tempParams);
        $httpBuidParams = Str::upper($httpBuidParams);

        $charArray = str_split($httpBuidParams);
        // 对字符数组进行排序
        sort($charArray);
        // 将排序后的字符数组转换回字符串
        $data = implode("", $charArray);

        $sign = hash_hmac("sha256", $data, $appSecret);
        echo $sign;
        

java代码

package com.xxx.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.ssc.common.security.annotation.SignIgnore;
import org.apache.commons.codec.digest.HmacUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 签名入参工具类
 *
 */

public class SignUtils {

    private static final ConcurrentMap<String, String[]> IGNORE_FIELD_CACHE = new ConcurrentHashMap<>();

    /**
     * 签名
     *
     * @param dto           原始参数
     * @param signType      签名算法
     * @param securityKey   加密key
     * @return 签名
     */
    public static String sign(Object dto, String signType, String securityKey) {
        if (Objects.isNull(dto)) {
            return "";
        }

        String[] ignoreFieldArray = getFieldNameByAnn(dto, com.ssc.common.security.annotation.SignIgnore.class);

        HmacUtils util = new HmacUtils(signType, securityKey);
        String sortStr = sortChar(buildPlainText(dto, ignoreFieldArray).toUpperCase());

        return util.hmacHex(sortStr);
    }

    /**
     * 校验签名
     *
     * @param dto           原始参数
     * @param signType      签名算法
     * @param securityKey   加密key
     * @param sign          签名串
     * @return  验证是否通过
     */
    public static boolean baseVerify(Object dto, String signType, String securityKey, String sign) {
        if (Objects.isNull(dto)) {
            return false;
        }

        String[] ignoreFieldArray = getFieldNameByAnn(dto, SignIgnore.class);

        HmacUtils util = new HmacUtils(signType, securityKey);
        String sortStr = sortChar(buildPlainText(dto, ignoreFieldArray).toUpperCase());

        String signVerify = util.hmacHex(sortStr);
        return Objects.equals(signVerify, sign);
    }

    public static Map<String, Object> obj2Map(Object dto, String... ignoreProperties) {
        CopyOptions options = new CopyOptions();
        options.setIgnoreProperties(ignoreProperties);
        return  BeanUtil.beanToMap(dto, new HashMap<>(), options);
    }

    public static String buildPlainText(Object dto, String... ignoreProperties ) {
        if (Objects.isNull(dto)) {
            return "";
        }

        Map<String, Object> map = obj2Map(dto, ignoreProperties);
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            sb.append(entry.getKey())
            .append("=")
            .append(entry.getValue())
            .append("&");
        }
        return sb.substring(0, sb.length() - 1);
    }

    public static String sortChar(String plainText) {
        if (StringUtils.isBlank(plainText)) {
            return "";
            }

            char[] charArray = plainText.toCharArray();
            Arrays.sort(charArray);

            return new String(charArray);
            }

            private String[] getFieldNameByAnn(Object object, Class<? extends Annotation> ann) {
            assert object != null;
            String[] ignoreFieldList = IGNORE_FIELD_CACHE.get(object.getClass().getName());
            if (Objects.isNull(ignoreFieldList)) {
            List<String> ignoreFields = new ArrayList<>();
            Class<?> entityType = object.getClass();
            while (entityType != null) {
            Field[] declaredFields = entityType.getDeclaredFields();
            for (Field declaredField : declaredFields) {
            if (declaredField.isAnnotationPresent(ann)) {
            ignoreFields.add(declaredField.getName());
            }
            }
            entityType = entityType.getSuperclass();

            }
            ignoreFieldList = ignoreFields.toArray(new String[0]);
            IGNORE_FIELD_CACHE.put(object.getClass().getName(), ignoreFieldList);
            }
            return ignoreFieldList;
            }


            @Target({ElementType.FIELD})
            @Retention(RetentionPolicy.RUNTIME)
            public @interface SignIgnore {

            }
            }
ackage com.xxx.dto;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.xxx.utils.SignUtils.SignIgnore;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;

/**
 * 签名DTO
 *
 */

@Data
public class BaseSignDTO implements Serializable {

    @SignIgnore
    @ApiModelProperty(value = "签名", required = true, example = "abcdefg")
    private String sign;

    @ApiModelProperty(value = "时间戳", required = true, example = "1663998514")
    private Long timestamp;

    @ApiModelProperty(value = "签名方式", required = true, example = "HmacSHA256")
    private String signType;

    @ApiModelProperty(value = "随机数", required = true, example = "12345")
    private String nonce;

    @ApiModelProperty(value = "应用Key", required = true)
    private String appKey;

    @ApiModelProperty(value = "应用密匙", hidden = true)
    private String appSecret;
}

 

标签:util,加密,String,java,return,import,dto,php
From: https://www.cnblogs.com/joshua317/p/18061072

相关文章

  • Java学习笔记——第九天
    综合项目:ATM项目需求拥有登陆界面,在登陆界面有开户、功能和退出系统功能。在开户时,要求输入姓名、性别、密码和每次取款限额,输入密码时要再输入一次以确认密码输入正确,之后自动生成不重复的8位数字卡号。在登陆时,若系统中没有账户,要能提示用户先去开户;若输入的账户不存在或密......
  • java 判断list对象中的一个属性值是否相同
    要判断Java中List对象的某个属性值是否全部相同,可以使用Java8的流(Stream)API来简化操作。以下是一个示例代码,演示如何检查一个对象列表中的某个属性是否全部相同:javaimportjava.util.List;importjava.util.Objects;publicclassListUtils{publicstatic<T>booleanal......
  • ThinkPHP常用方法
    对称加密对称加密可以用来把登录用户的id和name等少数信息http_build_query成一个字符串加密后放入cookie中。publicfunctionencryptString($content,$key){returnopenssl_encrypt($content,'AES-128-ECB',$key);}publicfunctiondec......
  • java 日期去掉T
    importjava.text.ParseException;importjava.text.SimpleDateFormat;importjava.util.Date;publicclassMain{publicstaticvoidmain(String[]args)throwsParseException{StringdateStr="2021-09-30T15:46:37";//原始日期字符串......
  • 【Java】Integer.parseInt()和Integer.valueOf()的区别
    1.Integer.parseInt()和Integer.valueOf()的区别区别1Integer.parseInt()将字符串转换为基本类型int,返回一个int类型值。inti=Integer.parseInt(Strings);Integer.valueOf()将字符串转换为Integer对象,返回一个Integer对象。Integeri=Integer.valueOf(Strings);......
  • AES白盒加密与密钥还原
    AES白盒加密主流的方法就是通过将原本的字节替换,行移位,列混淆和轮密钥加等操作用查表的方法实现,轮密钥则被合并到这些表中。可以通过DFA(DifferentialFaultAnalysis)差分故障分析来获取到正确的轮密钥,通过轮密钥结合密钥扩展算法得到原始密钥。常规AES加密此so的encryptPhoneN......
  • Java知识拓展
    publicclasstest3{publicstaticvoidmain(String[]args){//进制二进制0b十进制八进制0十六进制0xinti=10;inti2=010;inti3=0x10;System.out.println(i);System.out.println(i2);System.out.println(i3);System.out.println("=======......
  • JavaScript 常用取整、四舍五入方法汇总
    https://juejin.cn/post/7184257661339172919  2023-01-0314,624阅读2分钟 在JavaScript中,对数值进行四舍五入操作的场景有以下几种:向上取整:ceil向下取整:floor四舍五入:round固定精度:toFixed固定长度:toPrecision取整:parseInt1.向上取整:ceilceil是天花板......
  • java项目的根目录是指
    java项目的根目录是指Java项目的根目录是指在进行Java项目开发的过程中,我们经常会听到“项目的根目录”这个词汇。那么,什么是Java项目的根目录呢?Java项目的根目录指的是项目的主目录,也就是项目文件所在的最顶层目录。在这个目录下,通常会包含项目的源代码、配置文件、资源文件等......
  • Java 使用File对象 读取项目的根目录src下文件
    Java使用File对象读取项目的根目录src下文件在Java中,File对象的路径是相对于你运行Java程序的位置,或者是绝对路径。为了避免读取不到文件异常,你需要确保文件路径是正确的,并且文件确实存在于该路径上。有几种方法可以将文件放置在Java程序可以访问的位置:项目根目录:将logs.txt......