测试 Linux linux 嵌入式
使用RSA密钥产生函数RSA_generate_key_ex生成了一对密钥
// demo.cpp
#include
#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
#include
#include
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("%02x ",plain[i]);
}
printf("\n---------------\n");
outl=RSA_public_encrypt(strlen((char*)plain),plain,cipper,rsa,RSA_PKCS1_OAEP_PADDING);
for(int i =0;iprintf("%02x ",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;iprintf("%02x ",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 21
libcrypto.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;
$ ./config no-asm no-static-engine enable-shared --cross-compile-prefix=arm-none-linux-gnueabi-
$ ./Configure linux-elf no-asm no-static-engine enable-shared --cross-compile-prefix=arm-none-linux-gnueabi-
$ make
$ make install
或者根据需要加入安装路径参数
--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
#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 fail
setcontext和getcontext的使用
下面使用测试程序测试 setcontext ,getcontext ,makecontext 三个接口,是否能够在arm的板子上正确运行:
来自维基百科Setcontext条目的demo https://en.wikipedia.org/wiki/Setcontext
// ucontext.cpp
#include
#include
#include
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 world
This 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)或者互斥锁来实现相同的功能;