密码引擎的设计与实现
作者:互联网
实验一 密码引擎-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编码
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;
}
|
我们可以直接直接在原文件夹中生成。
一、 执行命令将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
编译过程:
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>
void tDigest()
{
unsigned char sm3_value[EVP_MAX_MD_SIZE]; //保存输出的摘要值的数组
int sm3_len, i;
EVP_MD_CTX *sm3ctx; //EVP消息摘要结构体
sm3ctx = EVP_MD_CTX_new(); //调用函数初始化
char msg1[] = "Test Message1" ; //待计算摘要的消息1
char msg2[] = "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" );
}
int main()
{
OpenSSL_add_all_algorithms();
tDigest();
return 0;
}
|
初始化函数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>
void tEVP_Encrypt()
{
unsigned char key[EVP_MAX_KEY_LENGTH]; //密钥
unsigned char iv[EVP_MAX_KEY_LENGTH]; //初始化向量
EVP_CIPHER_CTX* ctx; //EVP算法上下文
unsigned char out [1024]; //输出密文缓冲区
int outl; //密文长度
int outltmp;
const char *msg= "Hello OpenSSL" ; //待加密的数据
int rv;
int i;
//初始化函数才能用!
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,( const unsigned 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" );
}
int main()
{
OpenSSL_add_all_algorithms();
tEVP_Encrypt();
return 0;
}
|
编译、运行实现:
gcc -o mysm4 mysm4.c -lpthread -lcrypto ./mysm4 运行结果如下
执行命令
1 |
gcc -o mysm4 mysm4.c -lpthread -lcrypto
|
接下来放到云上试试~
可以发现也成功了!
在windows中重现:
标签:CTX,Base64,ctx,openssl,密码,引擎,printf,EVP,设计 来源: https://www.cnblogs.com/cindy123456/p/14875097.html