在使用LoadRunner时,当你录制完脚本后可能会发现在交互的数据中会存在密文,或者当拿到接口文档时就已经明确的描述出了交互数据的加解密方法,你该怎么办?

事实上这样的遭遇如今已经成为了一种常态,发送数据或接收到的数据中很难避免不出现密文,有些加密算法是自定义的方法,有些则是标准的对称或非对称加密算法。

很多时候对于像JMeter这样原生的Java程序测试工具来说,在高级语言特性、丰富的加解密算法库条件下,你可能一个简单的BeanShell处理器或自定义函数就可以轻松解决这些问题,但对于LoadRunner这种原生是C语言脚本的测试工具来说,为了能够发挥其自身在性能上巨大的优势,可能处理起来就没有那么轻松。

你将采取的方案
首先你要清楚选择LoadRunner作为性能测试工具的主要目的是什么?在JMeter、nGrinder等开源工具不断发展壮大,并且各自特点鲜明,不断蚕食着LoadRunner的优势地位,大有后来居上的情况下,你仍然甘愿花费重金或冒着侵权风险的条件下使用LoadRunner时,你必须清楚LoadRunner能够为你带来什么。

LoadRunner能成为行业标杆的前提是其优越的自身性能和丰富的协议支持。因此,你在使用它时也有必要将这两方面发挥到极致。一些建议是尽量避免使用LoadRunner的Java或C#.Net脚本,这样做会严重影响工具自身的性能,导致LoadRunner失去其巨大的性能优势,这也意味着在很大程度上就失去了使用它的价值。

下面我们按解决问题方案的优先级进行罗列:

方案一是使用C语言实现加解密过程,唯一麻烦的是LR在内存控制方面可能有一些小问题需要自己调试一下;

方案二是用Java这样可以支持long类型的语言编写一个外部的接口实现计算,可以在需要计算时使用一个HTTP请求这个接口;

方案三是使用参数,本地代码计算与用户对应形成加密数据的参数列表;

方案四才是使用Java脚本;

当然最后方案五是找开发改逻辑。

案例
曾经在群里就遇到了这样一个发送端数据加密传输的需求:
9位数字,比如987654321,前缀123,后缀456,组合成一个13位的数字123987654321456,之后乘以数字30,再进行base64编码计算。

方案一实现
这个需求对于Java语言来说简直小儿科,只需要引入org.apache.commons.codec参考以下代码:

long number = 987654321L;
number = Long.valueOf("123" + String.valueOf(number) + "456") * 30;
String token = new String(Base64.encodeBase64(String.valueOf(number).getBytes()));
System.out.println(token);
1
2
3
4
但对于LoadRunner下的C语言脚本,就需要稍微转动一下脑筋来实现这样的需求:

const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

Action()
{
char *a = "123987654321456";
char base64[4096];
char bigint[16];
bigint_muti(a, 30, bigint);
base64_encode(bigint, base64, sizeof(char) * 16);
lr_output_message("%s", base64);
return 0;
}

char *
get_bigint(const int high_bit, const int low_bit){
//内存区域分配大于8,否则high和low的内存会连在一起导致无法补0
char high[16];
char low[16];

char bigint[16];
int i = 8;

sprintf(high, "%d\0", high_bit);
sprintf(low, "%d\0", low_bit);

memset(bigint, '\0', sizeof(char) * 16);

//低位补0
if(strlen(low) < 8){
strcat(bigint, high);
for(i; i > strlen(low); i--){
strcat(bigint, "0");
}

strcat(bigint, low);

} else {
strcat(bigint, high);
strcat(bigint, low);
}

//尾部置0
if(high_bit < 10000000){
bigint[15] = 0;
} else {
bigint[16] = 0;
}

return bigint;
}

char *
bigint_add(char *a, char *b){
int a_length = strlen(a);
int b_length = strlen(b);
int a_high_bit, b_high_bit, a_low_bit, b_low_bit, low_total, high_total;
int a_high_length = a_length - 8;
int b_high_length = b_length - 8;
char a_high[8];
char b_high[8];
char a_low[8];
char b_low[8];
char bigint[16];
memset(a_high, '\0', sizeof(char) * 8);
memset(b_high, '\0', sizeof(char) * 8);
memset(a_low, '\0', sizeof(char) * 8);
memset(b_low, '\0', sizeof(char) * 8);
memset(bigint, '\0', sizeof(char) * 16);
strncpy(a_high, a, a_high_length);
strncpy(b_high, b, b_high_length);

a_high_bit = atoi(a_high);
b_high_bit = atoi(b_high);

a_low_bit = atoi(a + a_high_length);
b_low_bit = atoi(b + b_high_length);

low_total = a_low_bit + b_low_bit;

if(low_total > 99999999){
low_total = low_total % 100000000;
high_total = a_high_bit + b_high_bit + 1;
} else {
high_total = a_high_bit + b_high_bit;
}

return get_bigint(high_total, low_total);
}

void
bigint_muti(char *a, int b, char *bigint){
int i = 0;
strcpy(bigint, a);

for(i; i < (b - 1); i++){
strcpy(bigint, bigint_add(a, bigint));
}
return;

}
char *
base64_encode(const unsigned char * bindata, char *base64, int binlength){
int i, j;
unsigned char current;
lr_output_message("%s", bindata);
for ( i = 0, j = 0 ; i < binlength ; i += 3 )
{
current = (bindata[i] >> 2) ;
current &= (unsigned char)0x3F;
base64[j++] = base64char[(int)current];

current = ( (unsigned char)(bindata[i] << 4 ) ) & ( (unsigned char)0x30 ) ;
if ( i + 1 >= binlength )
{
base64[j++] = base64char[(int)current];
base64[j++] = '=';
base64[j++] = '=';
break;
}
current |= ( (unsigned char)(bindata[i+1] >> 4) ) & ( (unsigned char) 0x0F );
base64[j++] = base64char[(int)current];

current = ( (unsigned char)(bindata[i+1] << 2) ) & ( (unsigned char)0x3C ) ;
if ( i + 2 >= binlength )
{
base64[j++] = base64char[(int)current];
base64[j++] = '=';
break;
}
current |= ( (unsigned char)(bindata[i+2] >> 6) ) & ( (unsigned char) 0x03 );
base64[j++] = base64char[(int)current];

current = ( (unsigned char)bindata[i+2] ) & ( (unsigned char)0x3F ) ;
base64[j++] = base64char[(int)current];
}
base64[j] = '\0';
return base64;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

需要自己编写一个简单的大数加法(而且可以不普适实现),base64的C算法网上到处是,唯一麻烦的是LR在内存控制方面可能有一些小问题需要自己调试一下;

方案二实现
构建一个平行的Mock服务,几乎没有太多编码基础的测试工程师也可以通过NodeJS构建出一个加密计算的HTTP服务,参考如下代码:

const express = require('express');
const app = express();

app.get('/', function (req, res) {
if(req.query.number){
var number = req.query.number;
number = parseInt('123' + number + '456') * 30;
var token = (new Buffer(number.toString())).toString('base64');
res.send(JSON.stringify({
"token" : token
}));
} else {
res.send(JSON.stringify({
"status" : 500
}));
}

})

app.listen(80);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

于是可以通过请求该URL并将返回结果进行关联,便可以简单的将参数token进行赋值。
---------------------

LoadRunner中遭遇交互数据加密的处理方案的更多相关文章

  1. 前后端API交互数据加密——AES与RSA混合加密完整实例

    前言 前段时间看到一篇文章讲如何保证API调用时数据的安全性(传送门:https://blog.csdn.net/ityouknow/article/details/80603617),文中讲到利用R ...

  2. Redis 中常见的集群部署方案

    Redis 的高可用集群 前言 几种常用的集群方案 主从集群模式 全量同步 增量同步 哨兵机制 什么是哨兵机制 如何保证选主的准确性 如何选主 选举主节点的规则 哨兵进行主节点切换 切片集群 Redi ...

  3. 在.NET Core中遭遇循环依赖问题"A circular dependency was detected"

    今天在将一个项目迁移至ASP.NET Core的过程中遭遇一个循环依赖问题,错误信息如下: A circular dependency was detected for the service of ...

  4. js中getBoundingClientRect的作用及兼容方案

    js中getBoundingClientRect的作用及兼容方案 1.getBoundingClientRect的作用 getBoundingClientRect用于获取某个html元素相对于视窗的位 ...

  5. Loadrunner中web_find和web_reg_find函数的使用与区别

    总结一下Loadrunner中的检查点函数,主要介绍两个函数:web_find()和web_reg_find():这两个函数均用于内容的查找,但两者也有本质的区别,具体介绍如下:一.web_find( ...

  6. 0930MySQL中实现高性能高并发计数器方案(例如文章点击数)

    转自http://www.jb51.net/article/56656.htm 这篇文章主要介绍了MySQL中实现高性能高并发计数器方案,本文中的计数器是指如文章的点击数.喜欢数.浏览次数等,需要的朋 ...

  7. Loadrunner中Throughput(吞吐量)的分析与计算

    Throughput翻译为吞吐量,按照常规理解网络吞吐量表示在单位时间内通过网卡数据量之和,其中即包括本机网卡发送出去的数据量也包括本机网卡接收到的数据量,但这个理解在Loadrunner记录的Thr ...

  8. LoadRunner中循环操作

    Action() {     //Loadrunner中的FOR,WHILE,DO 循环语句 int i;   int whileloop = 1;   //FOR 循环   for (i=1;i&l ...

  9. 深入理解Loadrunner中的Browser Emulation

    深入理解Loadrunner中的Browser Emulation 深入理解Loadrunner中的Browser Emulation 3E?']V'VgB5n*S0一:基本介绍51Testing软件 ...

随机推荐

  1. fork me on github 彩带设置无效

    挑选彩带地址: https://github.com/blog/273-github-ribbons 发现代码复制粘贴过来,但是在自己博客园上无效,如粘贴如下代码 <a href="h ...

  2. 洛谷 P1186 玛丽卡

    P1186 玛丽卡 题目描述 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道 ...

  3. MySQL的limit用法及优化(转)

    常规用法: 用法一: OFFSET ; 比如这个SQL ,limit后面跟的是2条数据,offset后面是从第1条开始读取. 用法二: ,; 而这个SQL,limit后面是从第2条开始读,读取1条信息 ...

  4. OpenCV+iOS开发使用文档

      一.      前言     OpenCV是开源的跨平台的计算机视觉库,实现了图像处理.计算机视觉和机器学习的很多通用算法. 对于移动设备没有快速输入的键盘,大的屏幕,其优势在于图像和声音,因此要 ...

  5. css3中 弹性盒模型布局之box-flex

    box-flex:也就是让子容器针对父容器的宽高属性依照一定的规则来划分 Eg: html代码: <div class="wrap"> <div class=&q ...

  6. 通过telent、php深入了解http协议

    HTTP协议:简单点就是client怎么问.server如何答. 重要性:webservice 还是rest做大型架构都离不开对http协议的认识,甚至能够简化的说webservice =  http ...

  7. 在win10 64 bit上安装theano

    在windows10上安装theano,过程例如以下: 1.准备工作.先安装Anaconda 64位.然后执行 conda install mingw libpython 2.先安装pycuda,能够 ...

  8. 卸载完百度影音以后天气助手还在,而且总是自己主动打开ie浏览器,解决方式

    今天暴风影音不好用了.我就安装了百度影音,还有意外发现.相同的视频,用百度影音看不清楚,然后我就直接卸载了.结果卸掉以天气小助手还是在,而且总弹白色小框框,各种广告.最忍不了的是还自己主动打开ie浏览 ...

  9. @RestController注解的使用

    示例代码:/*@ResponseBody@Controller*/@RestControllerpublic class HelloController { @RequestMapping(" ...

  10. linux下dd命令详解【转】

    本文转载自:http://www.cnblogs.com/licheng/articles/1116492.html  名称: dd 使用权限: 所有使用者dd 这个指令在 manual 里的定义是 ...