基于padavan(openwrt) MIPS 的OpenSSL编译安装和编程小测
设备还是之前那个e8820s
先把gcc make perl装了
opkg install gcc make perl
这里有个问题,就是openssl 1.1.0之后的版本要求perl5.10,opkg安装的是5.28,运行./Configure会给报错
Can't locate FindBin.pm in @INC (you may need to install the FindBin module) (@INC contains: /opt/lib/perl5/5.28) at ./Configure line 15. BEGIN failed--compilation aborted at ./Configure line 15.
百度查了下用root用户执行就可以了,但是又查到这padavan编译的时候直接就不允许root登录了,默认的admin账户做不到这些,叫我自己编一个算了目前没力,有空可以搞个超频的玩玩
所以只能先用着没呢么多要求的1.1.0以下的版本了
源码地址https://www.openssl.org/source/old/,这次用的版本是openssl-1.1.0-pre1
wget 或者下下来再 winscp传都行,同样的网络,用wget下的很慢
传到默认文件夹/opt/home/admin
解压进去直接运行配置文件,编译就好了,mt7621性能就那样,得跑半个多小时
tar -zxvf openssl-1.1.1k.tar.gz cd tar -zxvf openssl-1.1.1k
./Configure
make
make install
最后 make install 的时候,会报错,不过好像对include和lib文件没什么影响
installing man1/CA.pl.1 /bin/sh: pod2man: not found make: *** [Makefile:677: install_docs] Error 127
好了可以小测一下了,这里用的是简单的大数计算
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <openssl/bn.h> //namespace dakuang {} int main(int argc, char* argv[]) { { // 计算加法 BIGNUM* pBNa = BN_new(); BIGNUM* pBNb = BN_new(); BIGNUM* pBNr = BN_new(); BN_set_word(pBNa, 1); BN_set_word(pBNb, 2); int ret = BN_add(pBNr, pBNa, pBNb); printf("BN_add ret:%d \n", ret); printf("BN_get_word:%d \n", BN_get_word(pBNr)); char* pR = BN_bn2dec(pBNr); printf("1+2=%s \n", pR); OPENSSL_free(pR); BN_free(pBNa); BN_free(pBNb); BN_free(pBNr); } { // 这里模拟了知道公钥的情况下,执行加密计算 // 计算次方 BN_CTX* pBNctx = BN_CTX_new(); BIGNUM* pBNr = BN_new(); BIGNUM* pBNa = BN_new(); BIGNUM* pBNp = BN_new(); BN_set_word(pBNa, 225); BN_set_word(pBNp, 29); int ret = BN_exp(pBNr, pBNa, pBNp, pBNctx); printf("BN_exp ret:%d \n", ret); char* pR = BN_bn2dec(pBNr); printf("225^29=%s \n", pR); OPENSSL_free(pR); // 计算除法 BN_CTX* pBNctx2 = BN_CTX_new(); BIGNUM* pBNdiv = BN_new(); BIGNUM* pBNrem = BN_new(); BIGNUM* pBNd = BN_new(); BN_set_word(pBNd, 323); ret = BN_div(pBNdiv, pBNrem, pBNr, pBNd, pBNctx2); printf("BN_div ret:%d \n", ret); pR = BN_bn2dec(pBNrem); printf("(225^29)%323=%s \n", pR); OPENSSL_free(pR); BN_free(pBNr); BN_free(pBNa); BN_free(pBNp); BN_free(pBNdiv); BN_free(pBNrem); BN_free(pBNd); BN_CTX_free(pBNctx); BN_CTX_free(pBNctx2); } { // 生成强随机数 BIGNUM* pBNr = BN_new(); int ret = BN_rand(pBNr, 8, -1, 1); printf("BN_rand ret:%d \n", ret); char* pR = BN_bn2dec(pBNr); printf("rand %s \n", pR); OPENSSL_free(pR); BN_free(pBNr); } { // 生成质数 BIGNUM* pBNr = BN_new(); int ret = BN_generate_prime_ex(pBNr, 16, 1, NULL, NULL, NULL); printf("BN_generate_prime_ex ret:%d \n", ret); char* pR = BN_bn2dec(pBNr); printf("prime %s \n", pR); OPENSSL_free(pR); BN_free(pBNr); } { // 计算最大公约数 BN_CTX* pBNctx = BN_CTX_new(); BIGNUM* pBNr = BN_new(); BIGNUM* pBNa = BN_new(); BIGNUM* pBNb = BN_new(); BN_set_word(pBNa, 10); BN_set_word(pBNb, 2); int ret = BN_gcd(pBNr, pBNa, pBNb, pBNctx); printf("BN_gcd ret:%d \n", ret); char* pR = BN_bn2dec(pBNr); printf("10 and 2 gcd %s \n", pR); OPENSSL_free(pR); BN_free(pBNr); BN_free(pBNa); BN_free(pBNb); BN_CTX_free(pBNctx); } return 0; }
编译执行
gcc -o to test.c -I /opt/home/admin/openssl-1.1.0-pre1/include -L /opt/home/admin/openssl-1.1.0-pre1 -lssl -lcrypto -lpthread -ldl
-I 和 -L 对应include和lib文件夹,不过编译出来的库文件在根目录,所以就直接写根目录了
注意-lssl -lcrypto要写在-ldl -lpthread前面,这四个必须要。
如果编译出来又运行不了,可以对执行文件用 ldd 看看是不是缺了哪个库文件
这个跑起来没问题
但这个base64的就跑不起来了,显示函数缺失,可能是1.1.0太老了
#include <stdio.h> #include <string.h> #include <openssl/evp.h> #include <openssl/x509.h> //Base64编码 void tEVP_Encode() { EVP_ENCODE_CTX *ctx; ctx = EVP_ENCODE_CTX_new(); //EVP编码结构体 unsigned char in[1024]; //输入数据缓冲区 int inl; //输入数据长度 char out[2048]={0}; //输出数据缓冲区 int outl; //输出数据长度 FILE *infp; //输入文件句柄 FILE *outfp; //输出文件句柄 infp = fopen("test.dat","rb");//打开待编码的文件 if(infp == NULL) { printf("Open File \"Test.dat\" for Read Err.\n"); return; } outfp = fopen("test.txt","w");//打开编码后保存的文件 if(outfp == NULL) { printf("Open File \"test.txt\" For Write Err.\n"); return; } EVP_EncodeInit(ctx);//Base64编码初始化 printf("文件\"Test.dat\" Base64编码后为:\n"); //循环读取原文,并调用EVP_EncodeUpdate计算Base64编码 while(1) { inl = fread(in,1,1024,infp); if(inl <= 0) break; EVP_EncodeUpdate(ctx,out,&outl,in,inl);//编码 fwrite(out,1,outl,outfp);//输出编码结果到文件 printf("%s",out); } EVP_EncodeFinal(ctx,out,&outl);//完成编码,输出最后的数据。 fwrite(out,1,outl,outfp); printf("%s",out); fclose(infp); fclose(outfp); printf("对文件\"Test.dat\" Base64编码完成,保存到\"test.txt\"文件.\n\n\n"); } //Base64解码 void tEVP_Decode() { EVP_ENCODE_CTX *ctx; ctx = EVP_ENCODE_CTX_new(); //EVP编码结构体 char in[1024]; //输入数据缓冲区 int inl; //输入数据长度 unsigned char out[1024]; //输出数据缓冲区 int outl; //输出数据长度 FILE *infp; //输入文件句柄 FILE *outfp; //输出文件句柄 infp = fopen("test.txt","r");//打开待解码的文件 if(infp == NULL) { printf("Open File \"Test.txt\" for Read Err.\n"); return; } outfp = fopen("test-1.dat","wb");//打开解码后保存的文件 if(outfp == NULL) { printf("Open File \"test-1.txt\" For Write Err.\n"); return; } EVP_DecodeInit(ctx);//Base64解码初始化 printf("开始对文件\"Test.txt\" Base64解码...\n\n"); //循环读取原文,并调用EVP_DecodeUpdate进行Base64解码 while(1) { inl = fread(in,1,1024,infp); if(inl <= 0) break; EVP_DecodeUpdate(ctx,out,&outl,in,inl);//Base64解码 fwrite(out,1,outl,outfp);//输出到文件 } EVP_DecodeFinal(ctx,out,&outl);//完成解码,输出最后的数据。 fwrite(out,1,outl,outfp); fclose(infp); fclose(outfp); printf("对文件\"Test.txt\" Base64解码完成,保存为\"test-1.dat\"\n\n\n"); } int main() { tEVP_Encode(); tEVP_Decode(); return 0; }
报错如下
/opt/bin/ld: /opt/tmp/ccpk2N8N.o: in function `tEVP_Decode': test2.c:(.text+0x35c): undefined reference to `EVP_ENCODE_CTX_new' /opt/bin/ld: test2.c:(.text+0x368): undefined reference to `EVP_ENCODE_CTX_new' collect2: error: ld returned 1 exit status
参考