密码引擎的设计与实现

Posted 20181217Cindy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了密码引擎的设计与实现相关的知识,希望对你有一定的参考价值。

实验一 密码引擎-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);
    //打印输出密文

(c)2006-2024 SYSTEM All Rights Reserved IT常识