编程语言Java接口签名(Signature)实现方案


Java接口签名(Signature)实现方案

大家好,我是程序员田同学!

今天上午收到一个需求,针对当前的系统开发一个对外开放的接口。

既然是对外开放,那么调用者一定没有我们系统的Token,就需要对调用者进行签名验证,签名验证采用主流的验证方式,采用Signature 的方式。

一、要求

下图为具体要求

二、流程

​ 1、线下分配appidappsecret,针对不同的调用方分配不同的appid和appsecret

  2、加入timestamp(时间戳),10分钟内数据有效

  3、加入流水号noncestr(防止重复提交),至少为10位。针对查询接口,流水号只用于日志落地,便于后期日志核查。 针对办理类接口需校验流水号在有效期内的唯一性,以避免重复请求。

  4、加入signature,所有数据的签名信息。

三、实现

简单来说,调用者调用接口业务参数在body中传递,header中额外增加四个参数signature、appkey、timestamp、noncestr。

我们在后台取到四个参数,其后三个参数加上调用者分配的appSecret,使用字典排序并使用MD5加密后与第一个参数signature进行比对,一致既表示调用者有权限调用。

以下代码为接口验证签名的demo实现:

   //引用jackson依赖
    @Autowired
    private ObjectMapper objectMapper;

    @Value("${appsecret}")
    private String appSecret;
  
  /**
     * 验证签名
     * @param preInfoItem
     * @return
     */
    boolean checkSignature(PreInfoItem preInfoItem) throws JsonProcessingException, IllegalAccessException {

        String signature="signature";

        String appkey="appkey";

        String timestamp="timestamp";

        String noncestr="noncestr";

        HttpServletRequest request = ServletUtils.getRequest();

        String headerSignature = request.getHeader(signature);
        String headerAppkey = request.getHeader(appkey);
        String headerTimestamp = request.getHeader(timestamp);
        String headerNoncestr = request.getHeader(noncestr);

		//因为需要排序,直接使用TreeMap
        Map parms=new TreeMap<>();
        parms.put(appkey,headerAppkey);
        parms.put(timestamp,headerTimestamp);
        parms.put(noncestr,headerNoncestr);


        Map stringObjectMap = objectToMap(parms, preInfoItem);
        String s = buildSignature(stringObjectMap);
        //签名比对
        if (s.equals(headerSignature)){
            return true;
        }
        return false;
    }

    Map objectToMap(Map map,Object o){
        Field[] declaredFields = o.getClass().getDeclaredFields();

        for (Field field : declaredFields) {
            field.setAccessible(true);

            try {
                if (field.getName() instanceof String){
                    map.put(field.getName(),field.get(o));
                }
            }catch (IllegalAccessException e){
                throw new CustomException("对象转map异常");
            }

        }
        return map;
    }

  private String buildSignature(Map maps){
      String s2;
      try {
            StringBuffer s = null;
            String s1 = objectMapper.writeValueAsString(maps);
            //添加appSecret
            s.append(s1).append(appSecret);
             s2 = DigestUtils.md5DigestAsHex(s.toString().getBytes());
        }catch (JsonProcessingException e){
            throw new CustomException("map转json异常");
        }

        return s2;
    }

好啦,赶快去试一下吧!

文章来源:https://www.cnblogs.com/tianClassmate/archive/2022/01/18/15819039.html

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现签名功能,可以使用Java的加密库中的数字签名API。 数字签名的基本过程如下: 1. 生成公私钥对 2. 使用私钥对原始数据进行签名 3. 使用公钥对签名进行验证 以下是一个简单的Java代码示例,实现数字签名的生成和验证: ```java import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; public class DigitalSignatureExample { public static void main(String[] args) throws Exception { // 生成公私钥对 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); // 原始数据 byte[] data = "Hello, world!".getBytes(); // 使用私钥对原始数据进行签名 Signature signature = Signature.getInstance("SHA256withRSA"); signature.initSign(privateKey); signature.update(data); byte[] signatureBytes = signature.sign(); // 使用公钥对签名进行验证 signature.initVerify(publicKey); signature.update(data); boolean verified = signature.verify(signatureBytes); System.out.println("Signature verified: " + verified); } } ``` 在上面的代码中,我们首先生成公私钥对,然后使用私钥对原始数据进行签名,最后使用公钥对签名进行验证。在实际应用中,签名需要与原始数据一起传输,接收方使用公钥进行验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值