密码引擎的设计与实现

实验一 密码引擎-0-OpenEuler ECS构建

登录自己的华为云账号,参考附件图示,构建基于鲲鹏和OpenEuler的ECS。

登录进OpenEuler系统,熟悉系统使用,注意OpenEuler安装工具使用sudo yum install ...

登录进OpenEuler系统,提交运行who命令的截图

加分项:使用yum install 安装C编程工具,以及自己的常用工具,提交安装后测试使用的截图。
构建基于鲲鹏和OpenEuler的ECS可参考华为云服务购买及基础实验,记得照着下图修改

密码引擎的设计与实现

登录进OpenEuler系统,熟悉系统使用,注意OpenEuler安装工具使用sudo yum install ...

 进入控制台,点击远程登录之后,点击CloudShell登录。

密码引擎的设计与实现

密码引擎的设计与实现

 填入设置的密码后,点击连接。

登录进OpenEuler系统,提交运行who命令的截图

密码引擎的设计与实现

加分项:使用yum install 安装C编程工具,以及自己的常用工具,提交安装后测试使用的截图。

密码引擎的设计与实现

密码引擎的设计与实现

实验一 密码引擎-1-OpenEuler-OpenSSL编译

1. 下载最新的OpenSSL源码
2. 用自己的8位学号建立一个文件夹,cd 你的学号,用pwd获得绝对路径
3. 参考https://www.cnblogs.com/rocedu/p/5087623.html先在Ubuntu中完成OpenSSL编译安装,然后在OpenEuler中重现
        ./config  --prefix=..(学号目录的绝对路径)指定OpenSSL编译链接
4. 提交 test_openssl.c 编译运行截图        
5. 加分项:在Windows中编译OpenSSL,记录编译过程,提交相关文档(推荐MarkDown格式)

 注:我的ubuntu用的是wsl(其实这个时候可以选择使用老师给的openssl-master也可以使用原来wsl自带的openssl)。

以下我使用老师提供的openssl-master:

 已知老师为我们提供了openssl-master.zip,首先我们可以解压缩到新创的20181217文件夹。

密码引擎的设计与实现

在wsl中的操作:

1 cd openssl-master 进入刚刚解压缩的文件夹

执行下面的操作:

1 2 3 4 5 ./configure make sudo make install

这样就安装好了。

安装好了之后,出现的问题及解决:

查看openssl版本时,出错了:
openssl: error while loading shared libraries: libssl.so.3: cannot open shared object file: No such file or directory

 经过上网查询,可知但我们输入这两条指令时,可以成功解决上述问题~

1 2 ln -s /usr/local/lib/libssl.so.3 /usr/lib/libssl.so.3 ln -s /usr/local/lib/libcrypto.so.3 /usr/lib/libcrypto.so.3

注意:到底是lib还是lib64需要自己进入文件夹去亲自查看。

再此查看openssl版本时,显示是成功的:

密码引擎的设计与实现

 在ubuntu下编译:

1 gcc -o to test_openssl.c -I /usr/local/ssl/inlcude -L /usr/local/ssl/lib -ldl -lpthread -lcrypto

密码引擎的设计与实现

 可知编译成功!

在华为云中,同样我们要安装openssl,和在wsl中安装的方式一模一样。(首先,我们要先创建20181217文件夹,然后可以直接把openssl-master.zip包拖到华为云的20181217文件夹下,再进行解压缩~)

出现了和wsl中一样的问题:

[root@ecs-cindy openssl-master]# openssl version  
openssl: error while loading shared libraries: libssl.so.3: cannot open shared object file: No such file or directory

 经过上网查询,可知但我们输入这两条指令时,可以成功解决上述问题~

1 2 ln -s /usr/local/lib/libssl.so.3 /usr/lib64/libssl.so.3 ln -s /usr/local/lib/libcrypto.so.3 /usr/lib64/libcrypto.so.3

密码引擎的设计与实现

可知最终编译成功了。

加分项:在Windows中编译OpenSSL,记录编译过程,提交相关文档

CodeBlocks配置openssl

  • 加静态库

    (先激活项目)菜单栏->Project->Build Options->Debug->Linker settings->Add 自己openssl安装目录下/lib下所有.lib文件(选择时使用Ctrl+A)

密码引擎的设计与实现

  • 加动态库

    菜单栏->Project->Build Options->Debug->Search directories->Linker->Add 动态库的目录(参考前面安装时的选项,设置后为/bin下)

密码引擎的设计与实现

  • 加头文件

菜单栏->Project->Build Options->Debug->Search directories->Compiler->Add 安装目录/include

密码引擎的设计与实现

测试Base64效果:

密码引擎的设计与实现

2.Virtual Studio 2019实现openssl编译

 eg:实现sm3:

密码引擎的设计与实现

 由此可知windows下openssl编译成功!

实验一 密码引擎-2-OpenEuler-OpenSSL测试

在Ubuntu编写代码测试OpenSSL功能,包含Base64,SM2,SM3,SM4算法的调用,然后在OpenEuler中重现
提交代码链接和运行结果截图

加分项:在Windows中重现(已重现)
代码链接:https://gitee.com/csq200215/csq/tree/master/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8%E7%B3%BB%E7%BB%9F%EF%BC%88%E4%B8%8B%EF%BC%89%E7%AC%AC%E4%B8%80%E6%AC%A1%E5%AE%9E%E9%AA%8C

Base64:(使用老师给我们的 Openssl-Test.zip)

1.在wsl实现

注意:老师给的代码在ubuntu下是不能跑通的,我们需要对EVP_Base64文件夹中的main.c文件进行修改(或者直接再重新生成一个Base64.c)

Base64.c如下:

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 #include <stdio.h> #include <string.h> #include <openssl/evp.h> #include <openssl/x509.h> //Base64编码 voidtEVP_Encode() {     EVP_ENCODE_CTX *ctx;         ctx = EVP_ENCODE_CTX_new();             //EVP编码结构体     unsigned charin[1024];         //输入数据缓冲区     intinl;                        //输入数据长度     charout[2048]={0};             //输出数据缓冲区     intoutl;                       //输出数据长度     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解码 voidtEVP_Decode() {     EVP_ENCODE_CTX *ctx;         ctx = EVP_ENCODE_CTX_new();         //EVP编码结构体     charin[1024];                  //输入数据缓冲区     intinl;                        //输入数据长度     unsigned charout[1024];        //输出数据缓冲区     intoutl;                       //输出数据长度     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");      }   intmain() {       tEVP_Encode();     tEVP_Decode();          return0; }

我们可以直接直接在原文件夹中生成。

密码引擎的设计与实现

一、 执行命令将Base64.c编译成可执行文件Base64。

1 gcc -o Base64 Base64.c -I /usr/local/ssl/inlcude -L /usr/local/ssl/lib -ldl -lpthread -lcrypto

密码引擎的设计与实现

 另一种执行方法~gcc -o Base64 Base64.c -lpthread -lcrypto

密码引擎的设计与实现

2.华为云

在OpenEuler中重现。

首先我们把下载好的 Openssl-Test.zip文件直接拖到华为云的20181217文件夹下。 

1 unzip  Openssl-Test.zip 实现解压缩。

进入Openssl-Test文件夹中,再进入EVP_Base64文件夹:

注意:老师给的代码在ubuntu下是不能跑通的,我们需要对EVP_Base64文件夹中的main.c文件进行修改(或者直接再重新生成一个Base64.c)。

和之前一样~

实现:

密码引擎的设计与实现

 可知可以成功实现。

在windows中重现:

密码引擎的设计与实现

二、实现SM2

sm2代码链接

编译过程:

gcc sm2_create_key_pair.c test_demo.c sm2_encrypt_and_decrypt.c test_sm2_encrypt_and_decrypt.c -o mysm2 -lcrypto

密码引擎的设计与实现

 执行过程:

密码引擎的设计与实现

密码引擎的设计与实现

密码引擎的设计与实现

 在华为云上运行过程:

密码引擎的设计与实现

运行结果:密码引擎的设计与实现

 可知成功实现。

在windows上的 VS中重现:

密码引擎的设计与实现

三、SM3

代码:

mysm3.c

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 #include <stdio.h> #include <string.h> #include <openssl/evp.h> voidtDigest() {     unsigned charsm3_value[EVP_MAX_MD_SIZE];   //保存输出的摘要值的数组     intsm3_len, i;     EVP_MD_CTX *sm3ctx;                         //EVP消息摘要结构体     sm3ctx = EVP_MD_CTX_new();//调用函数初始化     charmsg1[] = "Test Message1";              //待计算摘要的消息1     charmsg2[] = "Test Message2";              //待计算摘要的消息2          EVP_MD_CTX_init(sm3ctx);                    //初始化摘要结构体     EVP_DigestInit_ex(sm3ctx, EVP_sm3(), NULL); //设置摘要算法和密码算法引擎,这里密码算法使用sm3,算法引擎使用OpenSSL默认引擎即软算法     EVP_DigestUpdate(sm3ctx, msg1, strlen(msg1));//调用摘要UpDate计算msg1的摘要     EVP_DigestUpdate(sm3ctx, msg2, strlen(msg2));//调用摘要UpDate计算msg2的摘要      EVP_DigestFinal_ex(sm3ctx, sm3_value, &sm3_len);//摘要结束,输出摘要值        EVP_MD_CTX_reset(sm3ctx);                       //释放内存          printf("原始数据%s和%s的摘要值为:\n",msg1,msg2);     for(i = 0; i < sm3_len; i++)     {         printf("0x%02x ", sm3_value[i]);     }     printf("\n"); } intmain() {     OpenSSL_add_all_algorithms();     tDigest();     return0; }

初始化函数EVP_MD_CTX_init
函数功能:初始化一个 EVP_MD_CTX 结构体。只有调用该函数初始化后,EVP_MD_CTX结构体才能在其他函数中调用。
函数定义:
void EVP_MD_CTxinit(EVP MD CTX *ctx):

在ubuntu下实现:

执行命令:

1 gcc -o mysm3 mysm3.c -lpthread -lcrypto

密码引擎的设计与实现

 在华为云上实现:

密码引擎的设计与实现

在windows下的VS 2019中重现

密码引擎的设计与实现

四、SM4

代码:

mysm4.c :

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 #include <stdio.h> #include <string.h> #include <windows.h> #include <openssl/evp.h> #include <openssl/x509.h> voidtEVP_Encrypt() {     unsigned charkey[EVP_MAX_KEY_LENGTH];  //密钥     unsigned chariv[EVP_MAX_KEY_LENGTH];//初始化向量     EVP_CIPHER_CTX* ctx;//EVP算法上下文     unsigned charout[1024];//输出密文缓冲区     intoutl;//密文长度     intoutltmp;     constchar*msg="Hello OpenSSL";//待加密的数据     intrv;     inti;     //初始化函数才能用!         ctx = EVP_CIPHER_CTX_new();     //设置key和iv(可以采用随机数和可以是用户输入)     for(i=0;i<24;i++)     {         key[i]=i;     }     for(i=0;i<8;i++)     {         iv[i]=i;     }     //初始化密码算法结构体     EVP_CIPHER_CTX_init(ctx);     //设置算法和密钥以     rv = EVP_EncryptInit_ex(ctx,EVP_sm4_cbc(),NULL,key,iv);     if(rv!=1)     {         printf("Err\n");         return;     }     //数据加密     rv = EVP_EncryptUpdate(ctx,out,&outl,(constunsigned char*)msg,strlen(msg));     if(rv!=1)     {         printf("Err\n");         return;     }     //结束数据加密,把剩余数据输出。     rv = EVP_EncryptFinal_ex(ctx,out+outl,&outltmp);     if(rv!=1)     {         printf("Err\n");         return;     }     outl = outl +outltmp;     printf("原文为:%s\n",msg);     //打印输出密文     printf("密文长度:%d\n密文数据:\n",outl);     for(i=0;i<outl;i++)     {         printf("0x%02x ",out[i]);     }     printf("\n"); } intmain() {     OpenSSL_add_all_algorithms();     tEVP_Encrypt();     return0; }

  编译、运行实现:

gcc -o mysm4 mysm4.c -lpthread -lcrypto
./mysm4
运行结果如下

执行命令

1 gcc -o mysm4 mysm4.c -lpthread -lcrypto

密码引擎的设计与实现

 接下来放到云上试试~

密码引擎的设计与实现

 可以发现也成功了!

 在windows中重现:

密码引擎的设计与实现

 

上一篇:OpenSSL wiki


下一篇:PEM_read_RSA_PUBKEY error “Expecting: PUBLIC KEY”