记录下jmeter处理接口RSA+base64学习过程

Posted fkey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录下jmeter处理接口RSA+base64学习过程相关的知识,希望对你有一定的参考价值。

最近项目接口采用了RSA加密,之前的jmeter自动化脚本不能沿用了,我决定用beanshell来处理加密和解密完成自动化。

通过一天的折腾,加上开发大兄弟的援助,我这个java零基础的测试小白把rsa的加密解密方法搞出来了,idea运行成功加密和解密,代码如下:

技术图片
 1  1 package com.example.code.demo;
 2  2 
 3  3 import org.apache.commons.codec.binary.Base64;
 4  4 
 5  5 import javax.crypto.BadPaddingException;
 6  6 import javax.crypto.Cipher;
 7  7 import javax.crypto.IllegalBlockSizeException;
 8  8 import java.io.ByteArrayOutputStream;
 9  9 import java.io.IOException;
10 10 import java.nio.charset.Charset;
11 11 import java.nio.charset.StandardCharsets;
12 12 import java.security.KeyFactory;
13 13 import java.security.interfaces.RSAPrivateKey;
14 14 import java.security.interfaces.RSAPublicKey;
15 15 import java.security.spec.PKCS8EncodedKeySpec;
16 16 import java.security.spec.X509EncodedKeySpec;
17 17 
18 18 public class RsaTool {
19 19 
20 20     /** RSA最大加密明文大小 */
21 21     private static final int MAX_ENCRYPT_BLOCK = 245;
22 22     private static final Charset CHARSET = StandardCharsets.UTF_8;
23 23     /** RSA最大解密密文大小 */
24 24     private static final int MAX_DECRYPT_BLOCK = 256;
25 25 //    公鑰加密
26 26     public  String encrypt(String str, String publicKey) throws Exception {
27 27         //base64编码的公钥
28 28         byte[] decoded = Base64.decodeBase64(publicKey);
29 29         RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
30 30         //RSA加密
31 31         Cipher cipher = Cipher.getInstance("RSA");
32 32         cipher.init(Cipher.ENCRYPT_MODE, pubKey);
33 33         byte[] data = doSegmentFinal(cipher, str.getBytes(CHARSET), MAX_ENCRYPT_BLOCK);
34 34 //        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
35 35         String outStr = Base64.encodeBase64String(data);
36 36 //        String str = new String(outStr)
37 37         System.out.println("这是公钥加密后的字符: "+outStr);
38 38         return outStr;
39 39     }
40 40 //    私鑰解密
41 41     public  String decrypt(String str, String privateKey) throws Exception {
42 42         //64位解码加密后的字符串
43 43         byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
44 44         //base64编码的私钥
45 45         byte[] decoded = Base64.decodeBase64(privateKey);
46 46         RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
47 47         //RSA解密
48 48         Cipher cipher = Cipher.getInstance("RSA");
49 49         cipher.init(Cipher.DECRYPT_MODE, priKey);
50 50         byte[] data = doSegmentFinal(cipher,inputByte, MAX_DECRYPT_BLOCK);
51 51 //        String outStr = new String(cipher.doFinal(inputByte));
52 52         String outStr =  new String(data,StandardCharsets.UTF_8);
53 53         System.out.println("这是私钥解密后的字符: "+outStr);
54 54         return outStr;
55 55     }
56 56     private static byte[] doSegmentFinal(Cipher cipher, byte[] data, int segmentLength)
57 57             throws IOException, BadPaddingException, IllegalBlockSizeException {
58 58         try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
59 59             int inputLen = data.length;
60 60             int offSet = 0;
61 61             byte[] cache;
62 62             int i = 0;
63 63 
64 64             while (inputLen - offSet > 0) {
65 65                 if (inputLen - offSet > segmentLength) {
66 66                     cache = cipher.doFinal(data, offSet, segmentLength);
67 67                 } else {
68 68                     cache = cipher.doFinal(data, offSet, inputLen - offSet);
69 69                 }
70 70                 out.write(cache, 0, cache.length);
71 71                 i++;
72 72                 offSet = i * segmentLength;
73 73             }
74 74             return out.toByteArray();
75 75         }
76 76     }
77 77     public String msg(){
78 78         return "never mind scandal and liber";
79 79     }
80 80 }
RSA_code

接下来先试试用jmeter引用这个java文件

技术图片

哦豁,报错了

技术图片

 去找下万能的度娘,看看这是个啥问题.

百度了一大堆文章也只有一些无光痛痒的东西,所以我打算换个方式,用jmeter引用jar包再调用解密方法。

之前引用fasijson包解析过json数据,操作本身还是不算麻烦。

首先在idea里把项目打成jar包,然后把jar包路径配置到jmeter的任务里。(也可以将jar包放到jmeter/bin/lib/ext目录下直接引用。或者是修改properties文件,建立一个单独的依赖包目录,这类教程网上很多)

技术图片

  在beanshell取样器中引用jar包里的类,调用静态加密方法。 

技术图片

依然在报错,没有找到RsaTool类.这就让人很难受了.

再次去拜访度娘,看了十几个帖子,依然没找到有效办法,我就在想是不是这个java文件本身有问题。

我创建java项目时使用了spring boot这个框架,对这个框架的机制我完全不了解,我担心jemter没有识别到这框架的结构,于是新建了一个相对简洁方便一点的maven项目,

可是打包调用后依然遇到了以上问题。最后我决定返璞归真,建立一个最初始的java项目试试。

 

欸!好像能行

技术图片

方法能够成功调用,返回数据也是正常的。看来rsa加密没什么问题了,接下就是要根据接口文档处理入参和出参了。

 

请求接口的参数的规范是每个请求中将所有字段一起加密,作为data的值进行请求。

  1. {
  2. "data": "加密后的密文"
  3. }

我大概的请求思路是csv文档记录每一个字段的名字和值,自己再写一个java方法把字段拼接为json字符串,将json字符串传入rsa加密方法获取加密后的str,使用vars.get方法将str加载到jmeter变量parameters中,在http的post请求中调用${parameter},即可进行加密后的请求。

 

响应接口的参数规范和请求类似,只是多加了两个字段

  1. {
  2. "code": "0000",
  3. "message": "成功",
  4. "data": {
  5. "verifyCode": "000000"
  6. }
  7. }

接口会有参数关联,比如token和一些id。此时就需要从响应的data中拿到加密后的字符串,进行解析,拿到需要的数据。

大致思路是:用jemter自带的json提取器,将data的值及加密后的字符穿作为变量提取出来。再传入rsa解密方法,获得真实的json响应数据。利用alibaba的fastjson包解析数据,提取目标字段的值用于下一步的传参或者是断言(此处存疑,csv中也有参数,以谁为准)。

以上是关于记录下jmeter处理接口RSA+base64学习过程的主要内容,如果未能解决你的问题,请参考以下文章

Jmeter测试上传图片base64编码接口

关于Jmeter做Rsa加密解密的一些总结

Jmeter_前端RSA加密下的登陆模拟_引用js文件实现

jmeter URL base64编码遇到的问题

从 base64 RSA 公钥生成 SecKeyRef

jmeter处理加密接口