记录下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 }
接下来先试试用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的值进行请求。
{
"data": "加密后的密文"
}
我大概的请求思路是csv文档记录每一个字段的名字和值,自己再写一个java方法把字段拼接为json字符串,将json字符串传入rsa加密方法获取加密后的str,使用vars.get方法将str加载到jmeter变量parameters中,在http的post请求中调用${parameter},即可进行加密后的请求。
响应接口的参数规范和请求类似,只是多加了两个字段
{
"code": "0000",
"message": "成功",
"data": {
"verifyCode": "000000"
}
}
接口会有参数关联,比如token和一些id。此时就需要从响应的data中拿到加密后的字符串,进行解析,拿到需要的数据。
大致思路是:用jemter自带的json提取器,将data的值及加密后的字符穿作为变量提取出来。再传入rsa解密方法,获得真实的json响应数据。利用alibaba的fastjson包解析数据,提取目标字段的值用于下一步的传参或者是断言(此处存疑,csv中也有参数,以谁为准)。
以上是关于记录下jmeter处理接口RSA+base64学习过程的主要内容,如果未能解决你的问题,请参考以下文章