测试 Linux linux 嵌入式
使用RSA密钥产生函数RSA_generate_key_ex生成了一对密钥
// demo.cpp #include <stdio.h> #include "openssl/rsa.h" int main(){ RSA *rsa = RSA_new(); int ret = 0; BIGNUM* bne = BN_new(); ret=BN_set_word(bne,RSA_F4); ret = RSA_generate_key_ex(rsa,512,bne,NULL); if(ret!=1){ //FAILED }else{ //SUCCESS } return 0; } $ g++ demo.cpp -I./openssl-1.1.0e/_install/include/openssl -I./openssl-1.1.0e/_install/include -L./ libcrypto.a libssl.a -lpthread -ldl运行程序输出SUCCSS;
产生密钥,并使用公钥加密,使用私钥解密
#include <stdio.h> #include <string.h> #include <openssl/rsa.h> int main() { printf("\nRSA_generate_key_ex TESTING...\n\n"); RSA *rsa = RSA_new(); int ret = 0; BIGNUM *bne=BN_new(); ret=BN_set_word(bne,RSA_F4); ret = RSA_generate_key_ex(rsa,512,bne,NULL); unsigned char plain[512]="Hello world!"; unsigned char cipper[512]={0}; unsigned char newplain[512]={0}; size_t outl=512; size_t outl2; printf("%s\n", plain); for(int i =0;i<strlen((char*)plain);i++){ printf("x ",plain[i]); } printf("\n---------------\n"); outl=RSA_public_encrypt(strlen((char*)plain),plain,cipper,rsa,RSA_PKCS1_OAEP_PADDING); for(int i =0;i<outl;i++){ printf("x ",cipper[i]); if((i+1)%10 ==0) printf("\n"); } printf("\n"); outl2=RSA_private_decrypt(outl,cipper,newplain,rsa,RSA_PKCS1_OAEP_PADDING); printf("-----------------\n%s\n", newplain); for(int i =0;i<outl2;i++) { printf("x ",newplain[i]); } printf("\n"); return 0; } $ ./a.out RSA_generate_key_ex TESTING... Hello world! 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 --------------- 57 57 f1 3a 1b d9 60 e3 cd 4d 41 35 a0 63 9b f3 1d e7 a8 d4 3f a4 a3 25 66 ba 6b 9d 42 34 7f 7b 1d 98 83 0b d9 47 8c 8b aa 81 f1 ed c5 45 04 f2 af f5 98 30 de af ae d2 31 22 e1 32 71 e7 c8 0b ----------------- Hello world! 48 65 6c 6c 6f 20 77 6f 72 6c 64 21libcrypto.a,libssl.a库的编译; 开源库下载:https://www.openssl.org/source/ 下载版本 openssl-1.1.0e.tar.gz
$ ./config no-asm shared --prefix=$PWD/_install编译产生四个库 libcrypto.a libcrypto.so libssl.a libssl.so; 拷贝库文件出来,编译demo.cpp的目录结构:
|---demo.cpp |---libcrypto.a |---libssl.a |---openssl-1.1.0e/ |---openssl-1.1.0e/_install/ |---openssl-1.1.0e/_install/include/ |---openssl-1.1.0e/_install/include/openssl/网上大部分例程是使用了openssl-1.1.0e之前的版本,在该版本之前产生密钥都是使用了RSA_generate_key; 但是在openssl-1.1.0e版本上使用RSA_generate_key,编译阶段警告 RSA_generate_key…is deprecated… 在新版本中建议使用RSA_generate_key_ex;
或者根据需要加入安装路径参数
--prefix=$PWD/_install编译的是arm构架的库,所以修改 linux-elf 为 linux-armv4 使用仍然正常; 编译测试样例一、样例二成功并运行输出正确结果; 编译可执行程序的Makefile:
all: arm-none-linux-gnueabi-g++ demo.cpp \ -I/home/admin/project/debug/openssl-1.1.0e/include \ ${addprefix -L,/home/admin/project/debug/openssl-1.1.0e/lib} \ -lssl -lcrypto -lm -lpthread -ldl测试过程中使用了大概有4个版本的openssl库 openssl-1.0.2 openssl-1.0.2l openssl-1.0.2j openssl-1.1.0e
在移植过程中发生了一些意外,如果使用下面的配置编译会出现问题(直接gcc基础上加上cross-compile-prefix) 而不配置Configure的相关属性
$ ./config no-asm shared --prefix=$PWD/_install --cross-compile-prefix=arm-none-linux-gnueabi- $ make产生两个问题 1 编译时报m64字段的错误(需要手动删除Makefile文件中的两处m64字段) 2 在开发板上运行报错,并且编译阶段就有警告(getcontext/setcontext/makecontext未实现,允许忽略不处理) 3 编译后的应用程序使用报错(crypto/bn/bn_gcd.c/BN_mod_inverse函数产生BIGNUM的d[0]错误参数)
于是写了DEMO:
#include <stdio.h> #include "openssl/rsa.h" int main(){ RSA * rsa =RSA_generate_key(1024,RSA_3,NULL,NULL); printf("%p\n", rsa); return 0; }编译的测试样例一也是出现一样的错误(BIGNUM的d[0]参数错误);
在宿主机上运行正确;在板子上运行则是进入了死循环; 使用交叉编译工作编译时,在编译阶段出现的警告
warning: warning: getcontext is not implemented and will always fail warning: warning: setcontext is not implemented and will always fail warning: warning: makecontext is not implemented and will always failsetcontext和getcontext的使用 下面使用测试程序测试 setcontext ,getcontext ,makecontext 三个接口,是否能够在arm的板子上正确运行: 来自维基百科Setcontext条目的demo https://en.wikipedia.org/wiki/Setcontext
// ucontext.cpp #include <stdio.h> #include <ucontext.h> #include <unistd.h> int main(int argc, char *argv[]) { ucontext_t context; getcontext(&context); puts("Hello world"); sleep(1); setcontext(&context); return 0; }运行:
$ g++ ucontext.cpp $ ./a.out Hello world Hello world Hello world Hello world Hello worldThis makes an infinite loop because context holds the program counter. (这是一个无限循环因为语境保持程序计数器.)
使用交叉编译工具在开发板上进行测试
$ arm-none-linux-gnueabi-g++ ucontext.cpp /tmp/ccSGOIfY.o: In function `main': ucontext.cpp:(.text+0x1c): warning: warning: getcontext is not implemented and will always fail ucontext.cpp:(.text+0x38): warning: warning: setcontext is not implemented and will always fail $ ./a.out $ Hello world $在Linux嵌入式板子上运行后,没有循环输出 Hello world;
暂时没有找到较为完整的解决办法,建议使用线程(pthread)或者互斥锁来实现相同的功能;