Forest请求前置操作RSA签名加密

前言

在很多时候为了安全需要将请求的参数签名签名加密,使用非对称加密-RSA,非对称加密有供钥和私钥两个概念,私钥自己拥有,不能给别人,公钥公开,根据应用的不同,我们可以选择不同的密钥加密,
1:签名:使用私钥加密,公钥解密。用于让所有公钥所有者验证私钥所有者的身份并且用来防止私钥所有者发布的内容被篡改,但是不能保证内容不被他人获得,
2:加密:用公钥加密,私钥解密,用于向公钥所有者发布信息,这个信息可能被他人篡改,但是无法被他人获得。

这里需要调其他平台项目的接口,需要对请求的参数进行签名,RSA算法采用默认补位方式RSA/ECB/PKCS1Padding

一、Forest

Forest 是一个开源的 Java HTTP 客户端框架,它能够将 HTTP 的所有请求信息(包括 URL、Header 以及 Body 等信息)绑定到您自定义的 Interface 方法上,能够通过调用本地接口方法的方式发送 HTTP 请求。
使用 Forest 就像使用类似 Dubbo 那样的 RPC 框架一样,只需要定义接口,调用接口即可,不必关心具体发送 HTTP 请求的细节。同时将 HTTP 请求信息与业务代码解耦,方便您统一管理大量 HTTP 的 URL、Header 等信息。而请求的调用方完全不必在意 HTTP 的具体内容,即使该 HTTP 请求信息发生变更,大多数情况也不需要修改调用发送请求的代码。
这里使用Forest来做客户端使用。

二、项目使用

项目配置

forest:
  max-connections: 100
  timeout: 3000
  connect-timeout: 3000
  read-timeout: 3000
  variables:
    phpUrl: http://xxxxxx.com

编写接口

@BaseRequest(baseURL = "${phpUrl}", interceptor = PhpRequestInterceptor.class)
public interface PhpRequestClient {

    /**
     * xxxx
     * @param body 请求数据
     * @return
     */
    @Post(url = "/syncLabel")
    Boolean syncLabel(@Body("data") String body);

    /**
     * xxxx
     * @param body 请求数据
     * @return
     */
    @Post(url = "/syncClassification")
    Boolean syncClassification(@Body("data") String body);
}

这里使用post请求,由于这个平台的多个接口都需要进行签名,所以在forest拦截器当中进行签名,定义新的拦截器实现Interceptor

/**
 * php接口请求拦截器
 * @author liufuqiang
 */
public class PhpRequestInterceptor<T> implements Interceptor<T> {

    @Override
    public void onInvokeMethod(ForestRequest request, ForestMethod method, Object[] args) {
        if (ForestRequestType.POST.equals(request.getType())) {
            ForestBody body = request.getBody();
            List<NameValueRequestBody> bodyList = body.getNameValueItems();
            for (NameValueRequestBody bodyItem : bodyList) {
                bodyItem.setValue(encryptRequestBody(String.valueOf(bodyItem.getValue())));
            }
        }
    }

    @Override
    public boolean beforeExecute (ForestRequest request) {
        return true;
    }

    private final static String PHP_SIGN_PRIVATE_KEY = "私钥";

    private final static String PHP_SIGN_PUBLIC_KEY = "公钥";

    private String encryptRequestBody (String params) {
        RSA rsa = new RSA(PHP_SIGN_PRIVATE_KEY, PHP_SIGN_PUBLIC_KEY);
        return rsa.encryptBase64(params, KeyType.PrivateKey);
    }
}


拦截器写完需要在指定地方进行注入

发送HTTP请求不可能一直是成功的,总有失败的时候,这里如果不想在每个地方进行try catch捕捉异常,可以将请求的返回类型该为你ForestResponse,然后在拦截器的onError方法中即可全局进行捕捉异常。

最后发送请求可以在控制台看到请求体为加密之后的数据

文档
https://hutool.cn/docs/#/crypto/%E9%9D%9E%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86-AsymmetricCrypto
https://forest.dtflyx.com/pages/1.5.x/install_guide/

posted @ 2022-11-16 21:05  木马不是马  阅读(542)  评论(0编辑  收藏  举报