使用 openssl speed [value] 可以测试某项算法的执行速度。
可以直接执行 openssl speed rsa,让他依次去计算 512bit、1024bit、2048bit、4096bit 的效率;也可以单独执行 openssl speed rsa512 来算。
在 PIII 700 上的结果为
sign verify sign/s verify/s rsa 512 bits 0.0021s 0.0002s 475.4 5199.0 rsa 1024 bits 0.0102s 0.0005s 97.7 1883.4 rsa 2048 bits 0.0592s 0.0017s 16.9 582.2 rsa 4096 bits 0.3912s 0.0055s 2.6 181.9
speed 参数还支持 -multi n 参数来进行并发操作。在 PIII 700 双CPU 情况下并不是成倍增长,很奇怪。不过可能因为那台机器当时还有其他负载的缘故。
按照《应用密码学》里的建议(Applied Cryptography),2007 年企业应用应该考虑 1536bit,但 openssl speed 不支持1536bit的benchmark,于是自己写了一个程序来计算效率。
-
/*
-
* openssl genrsa -out rsa1536.key 1536
-
* openssl rsa -pubout < rsa1536.key > rsa1536.pub
-
* gcc -o benchmark benchmark.c -lcrypto
-
*
-
*/
-
#include <unistd.h>
-
#include <signal.h>
-
#include <stdio.h>
-
#include <string.h>
-
#include <openssl/rsa.h>
-
#include <openssl/pem.h>
-
-
int global_flag = 0;
-
void signal_alrm(int sig)
-
{
-
global_flag = 1;
-
}
-
-
int main(int argc, char *argv[])
-
{
-
char *buf;
-
int size, ret;
-
FILE *pubfp;
-
FILE *prifp;
-
RSA *pub;
-
RSA *pri;
-
int i;
-
-
OpenSSL_add_all_algorithms();
-
ERR_load_crypto_strings();
-
-
pubfp = fopen("rsa1536.pub", "r");
-
prifp = fopen("rsa1536.key", "r");
-
pub = (RSA *)PEM_read_RSA_PUBKEY(pubfp, NULL, NULL, NULL);
-
pri = (RSA *)PEM_read_RSAPrivateKey(prifp, NULL, NULL, NULL);
-
fclose(pubfp);
-
fclose(prifp);
-
-
if (pri == NULL) {
-
printf("PEM_read_RSAPrivateKey error\n");
-
ERR_print_errors_fp(stderr);
-
return 1;
-
} else if (pub == NULL) {
-
printf("PEM_read_RSA_PUBKEY error\n");
-
ERR_print_errors_fp(stderr);
-
RSA_free(pub);
-
return 1;
-
}
-
-
size = RSA_size(pri);
-
buf = (char *)malloc(size);
-
-
signal(SIGALRM, signal_alrm);
-
alarm(10);
-
i = global_flag = 0;
-
while (1) {
-
if (0 == RSA_sign(NID_md5, "0123456789abcdef", 16, buf, &ret, pri)) {
-
printf("RSA_sign error\n");
-
ERR_print_errors_fp(stderr);
-
free(buf); RSA_free(pub); RSA_free(pri);
-
return 1;
-
}
-
i++;
-
if (global_flag) break;
-
}
-
printf("RSA_sign: %d\n", i);
-
-
i = global_flag = 0;
-
alarm(10);
-
while (1) {
-
if (0 == RSA_verify(NID_md5, "0123456789abcdef", 16, buf, ret, pub)) {
-
printf("RSA_verify error\n");
-
ERR_print_errors_fp(stderr);
-
free(buf); RSA_free(pub); RSA_free(pri);
-
return 1;
-
}
-
i++;
-
if (global_flag) break;
-
}
-
printf("RSA_verify: %d\n", i);
-
-
free(buf); RSA_free(pub); RSA_free(pri);
-
return 0;
-
}
10秒种内 sign/verify 一个长度为 16 位的字符串结果如下:
PIII 700 330/8680
XEON 2.4G 666/17034
XEON 3.0G 799/22633
XEON 5130/2.0G 1053/29154
感觉这样的效率还是不错的,需要在实际系统中进一步小心的验证。
还有就是 openssl 编译优化的问题。为了测试 ECC 的支持,我自己编译了 openssl-0.9.8。结果发现在计算 rsa512 的时候,我编译的 openssl(采取缺省configure) 比系统缺省的 openssl 慢了 10% (470 vs 420)。改了改config,可以提升到 450 左右,后来就没有再仔细琢磨下去。
最后用 openssl 0.9.8d 测试了一下 ECC 的签名校验效率(ECDSA),执行 openssl speed ecdsa (PIII 700)
sign verify sign/s verify/s 160 bit ecdsa (secp160r1) 0.0013s 0.0061s 786.1 162.9 192 bit ecdsa (nistp192) 0.0013s 0.0062s 774.7 160.4 224 bit ecdsa (nistp224) 0.0016s 0.0079s 616.5 126.4 256 bit ecdsa (nistp256) 0.0020s 0.0101s 503.8 99.0 384 bit ecdsa (nistp384) 0.0046s 0.0249s 218.5 40.1 521 bit ecdsa (nistp521) 0.0097s 0.0519s 103.0 19.3 163 bit ecdsa (nistk163) 0.0046s 0.0125s 219.8 80.3 233 bit ecdsa (nistk233) 0.0090s 0.0240s 110.7 41.6 283 bit ecdsa (nistk283) 0.0140s 0.0447s 71.5 22.4 409 bit ecdsa (nistk409) 0.0315s 0.1063s 31.7 9.4 571 bit ecdsa (nistk571) 0.0705s 0.2507s 14.2 4.0 163 bit ecdsa (nistb163) 0.0046s 0.0133s 218.8 74.9 233 bit ecdsa (nistb233) 0.0091s 0.0268s 110.3 37.3 283 bit ecdsa (nistb283) 0.0141s 0.0506s 71.2 19.8 409 bit ecdsa (nistb409) 0.0316s 0.1224s 31.7 8.2 571 bit ecdsa (nistb571) 0.0704s 0.2877s 14.2 3.5
签名速度还可以,就是校验速度慢死了..
评论
openssl真不错
刚还网上找了半天,想找个RSA的指标,结果一直没找到,想起来openssl,再一搜到这里了,果然可以做。