一.什么是RSA算法

RSA加密算法是一种非对称加密算法。通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。

二.使用openssl生成秘钥

打开openssl工具

  1. 生成私钥, 最后一个参数可修改长度
openssl genrsa -out ../mycerts/rsa_private_key.pem 2048`
  1. 根据私钥生成公钥
openssl rsa -in ../mycerts/rsa_private_key.pem -pubout -out ../mycerts/rsa_public_key_2048.pub`
  1. 将私钥转换成为pkcs8格式
pkcs8 -topk8 -inform PEM -in ../mycerts/rsa_private_key.pem -outform PEM -nocrypt -out ../mycerts/rsa_private_key_pkcs8.pem

PKCS#1 定义了RSA公钥函数的基本格式标准,特别是数字签名。
PKCS#2 涉及了RSA的消息摘要加密,已被并入PKCS#1中。
PKCS#3 Diffie-Hellman密钥协议标准。
PKCS#4 最初是规定RSA密钥语法的,现已经被包含进PKCS#1中。
PKCS#5
基于口令的加密标准,描述了使用由口令生成的密钥来加密8位位
组串并产生一个加密的8位位组串的方法。PKCS#5可以用于加密私
钥,以便于密钥的安全传输(这在PKCS#8中描述)。
PKCS#6
扩展证书语法标准,定义了提供附加实体信息的X.509证书属性扩
展的语法。
PKCS#7
密码消息语法标准。为使用密码算法的数据规定了通用语法,比如
数字签名和数字信封。
PKCS#8
私钥信息语法标准。定义了私钥信息语法和加密私钥语法,其中私

钥加密使用了PKCS#5标准。
PKCS#9 可选属性类型。
PKCS#10 证书请求语法标准。
PKCS#11 密码令牌接口标准。
PKCS#12 个人信息交换语法标准。
PKCS#13 椭圆曲线密码标准。
PKCS#14 伪随机数产生标准。
PKCS#15 密码令牌信息语法标准

三.rsa工具类(可以从资源中找到,此处为记录本地位置)

工具类见本地D:/mproj/tensquare_encrypt下rsa和service包
相关测试类见本地D:/mproj/tensquare_encrypt/test下Encrypttest

主要使用工具类rsaservice的RSAEncryptDataPEM和RSADecryptDataPEM方法来实现对接口加密解密测试

四.工具类应用

  1. 首先替换工具类中RSAkeys中的公钥私钥为自己生成的,私钥直接替换成pkcs8格式的
  2. 新建过滤器,在run方法中进行加密解密
@Override
    public Object run() throws ZuulException {
        //过滤器具体执行的逻辑
        System.out.println("过滤器执行了");
        //获取requestContext容器
        RequestContext ctx=RequestContext.getCurrentContext();
        HttpServletRequest request=ctx.getRequest();
        HttpServletResponse response=ctx.getResponse();

        //声明存放加密后数据的变量
          String requestData=null;
          //声明存放解密后数据的变量
        String decryptData=null;
        //通过request获取inputStream
        try {
            ServletInputStream inputStream=request.getInputStream();
            //从inputStream中得到加密后的数据
            requestData= StreamUtils.copyToString(inputStream, Charsets.UTF_8);
            System.out.println("****************************"+requestData+"**********************");
            if(!Strings.isNullOrEmpty(requestData)){
              decryptData=rsaService.RSADecryptDataPEM(requestData,RsaKeys.getServerPrvKeyPkcs8());
                System.out.println("!!!!!!!!!!!!!!"+decryptData+"!!!!!!!!!!!!!!!!!!!!!!!!");
            }
            //解密后数据转发给文章微服务,需要放到request中
           if(!Strings.isNullOrEmpty(decryptData)){
//获取解密后的字节数组
               byte[] bytes=decryptData.getBytes();
                //使用RequestContext
                ctx.setRequest(new HttpServletRequestWrapper(request){


                    @Override
                    public int getContentLength() {
                        return bytes.length;
                    }

                    @Override
                    public long getContentLengthLong() {
                        return bytes.length;
                    }

                    @Override
                    public ServletInputStream getInputStream() throws IOException {
                        return new ServletInputStreamWrapper(bytes);
                    }
                });
           }

//需要设置request请求头中的Content-Type为json格式
            //不设置,api接口模块就需要进行url转码的操作
            ctx.addZuulRequestHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE+";charset=UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}

其中httpServletRequest的inputStream是不允许手动修改的,没有setInputStream方法,所以重写request的getInputStream方法,同时还需要重写getContentLength和getContentLengthLong。