课设第二周进展
本周计划完成的任务:
找到1,2个C语言下的支持国密算法的加密算法库
本周实际完成的任务:
找到C语言下的阿里巴巴算法库babassl库,铜锁/Tongsuo(原BabaSSL)是一个提供现代密码学算法和安全通信协议的开源基础密码库,为存储、网络、密钥管理、隐私计算等诸多业务场景提供底层的密码学基础能力,实现数据在传输、使用、存储等过程中的私密性、完整性和可认证性,为数据生命周期中的隐私和安全提供保护能力。
实践过程:
探索babassl是否支持国密
查找官方git链接
https://gitcode.net/mirrors/babassl/babassl
安装babassl库
从git里下载下安装包后解压缩
在解压后的地址下configure编译后make
之后sudo make install
完成安装
安装后openssl version
可查看babassl版本
babassl国密实践
1.SM2证书签发
生成SM2私钥
openssl ecparam -genkey -name SM2 -out sm2.key
生成证书签名请求 csr
openssl req -new -key sm2.key -out sm2.csr -sm3 -sigopt "sm2_id:1234567812345678"
生成证书(一般用于自签名测试证书)
openssl x509 -req -in sm2.csr -signkey sm2.key -out sm2.crt -sm3 -sm2-id 1234567812345678 -sigopt "sm2_id:1234567812345678"
2.ZUC算法实践
开启ZUC算法
./config enable-zuc
测试代码
#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
int main(int argc, char *argv[])
{
EVP_MD_CTX *mctx = NULL;
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *pkey = NULL;
unsigned char *got = NULL;
size_t got_len;
char *mac;
int rv;
const char key[] = {
0xc9, 0xe6, 0xce, 0xc4, 0x60, 0x7c, 0x72, 0xdb,
0x00, 0x0a, 0xef, 0xa8, 0x83, 0x85, 0xab, 0x0a
};
/*
* EIA3 的 iv 只有5个字节(只用到38bit),不是随机构造,构造方法如下:
* |----------32bit----------|-----5bit-----|---1bit---|
* | count | bearer | direction|
*/
const char *iv = "a94059da54";
const char msg[] = {
0x98, 0x3b, 0x41, 0xd4, 0x7d, 0x78, 0x0c, 0x9e,
0x1a, 0xd1, 0x1d, 0x7e, 0xb7, 0x03, 0x91, 0xb1,
0xde, 0x0b, 0x35, 0xda, 0x2d, 0xc6, 0x2f, 0x83,
0xe7, 0xb7, 0x8d, 0x63, 0x06, 0xca, 0x0e, 0xa0,
0x7e, 0x94, 0x1b, 0x7b, 0xe9, 0x13, 0x48, 0xf9,
0xfc, 0xb1, 0x70, 0xe2, 0x21, 0x7f, 0xec, 0xd9,
0x7f, 0x9f, 0x68, 0xad, 0xb1, 0x6e, 0x5d, 0x7d,
0x21, 0xe5, 0x69, 0xd2, 0x80, 0xed, 0x77, 0x5c,
0xeb, 0xde, 0x3f, 0x40, 0x93, 0xc5, 0x38, 0x81,
0x00
};
size_t msg_len = 73;
/*
* 将 EIA3 的 key 转换成 EVP_PKEY
*/
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_EIA3, NULL, key, 16);
if (pkey == NULL)
goto end;
mctx = EVP_MD_CTX_new();
if (mctx == NULL)
goto end;
if (!EVP_DigestSignInit(mctx, &pctx, NULL, NULL, pkey))
goto end;
/*
* 设置 EIA3 的 iv,其中 iv 是十六进制的字符串形式
* 也可以设置 hexkey 来修改 key,同样是十六进制的字符吕形式
*/
rv = EVP_PKEY_CTX_ctrl_str(pctx, "iv", iv);
if (rv <= 0)
goto end;
if (!EVP_DigestSignUpdate(mctx, msg, msg_len))
goto end;
if (!EVP_DigestSignFinal(mctx, NULL, &got_len))
goto end;
got = OPENSSL_malloc(got_len);
if (got == NULL)
goto end;
if (!EVP_DigestSignFinal(mctx, got, &got_len))
goto end;
/*
* EIA3 的 mac 值为4个字节,这里打印出来
*/
mac = OPENSSL_buf2hexstr(got, got_len);
printf("MAC=%s\n", mac);
OPENSSL_free(mac);
end:
EVP_MD_CTX_free(mctx);
OPENSSL_free(got);
EVP_PKEY_free(pkey);
return 0;
}
输出结果
同态加密EC-ELGamal实践
demo代码
#include <stdio.h>
#include <time.h>
#include <openssl/ec.h>
#include <openssl/pem.h>
#define CLOCKS_PER_MSEC (CLOCKS_PER_SEC/1000)
int main(int argc, char *argv[])
{
int ret = -1;
uint32_t r;
clock_t begin, end;
EC_KEY *sk_eckey = NULL, *pk_eckey = NULL;
EC_ELGAMAL_CTX *ctx1 = NULL, *ctx2 = NULL;
EC_ELGAMAL_CIPHERTEXT *c1 = NULL, *c2 = NULL, *c3 = NULL;
EC_ELGAMAL_DECRYPT_TABLE *table = NULL;
FILE *pk_file = fopen("ec-pk.pem", "rb");
FILE *sk_file = fopen("ec-sk.pem", "rb");
if ((pk_eckey = PEM_read_EC_PUBKEY(pk_file, NULL, NULL, NULL)) == NULL)
goto err;
if ((sk_eckey = PEM_read_ECPrivateKey(sk_file, NULL, NULL, NULL)) == NULL)
goto err;
if ((ctx1 = EC_ELGAMAL_CTX_new(pk_eckey)) == NULL)
goto err;
if ((ctx2 = EC_ELGAMAL_CTX_new(sk_eckey)) == NULL)
goto err;
begin = clock();
if ((table = EC_ELGAMAL_DECRYPT_TABLE_new(ctx2, 0)) == NULL)
goto err;
EC_ELGAMAL_CTX_set_decrypt_table(ctx2, table);
end = clock();
printf("EC_ELGAMAL_DECRYPT_TABLE_new(1) cost: %lfms\n", (double)(end - begin)/CLOCKS_PER_MSEC);
if ((c1 = EC_ELGAMAL_CIPHERTEXT_new(ctx1)) == NULL)
goto err;
if ((c2 = EC_ELGAMAL_CIPHERTEXT_new(ctx1)) == NULL)
goto err;
begin = clock();
if (!EC_ELGAMAL_encrypt(ctx1, c1, 20000021))
goto err;
end = clock();
printf("EC_ELGAMAL_encrypt(20000021) cost: %lfms\n", (double)(end - begin)/CLOCKS_PER_MSEC);
begin = clock();
if (!EC_ELGAMAL_encrypt(ctx1, c2, 500))
goto err;
end = clock();
printf("EC_ELGAMAL_encrypt(500) cost: %lfms\n", (double)(end - begin)/CLOCKS_PER_MSEC);
if ((c3 = EC_ELGAMAL_CIPHERTEXT_new(ctx1)) == NULL)
goto err;
begin = clock();
if (!EC_ELGAMAL_add(ctx1, c3, c1, c2))
goto err;
end = clock();
printf("EC_ELGAMAL_add(C2000021,C500) cost: %lfms\n", (double)(end - begin)/CLOCKS_PER_MSEC);
begin = clock();
if (!(EC_ELGAMAL_decrypt(ctx2, &r, c3)))
goto err;
end = clock();
printf("EC_ELGAMAL_decrypt(C20000021,C500) result: %d, cost: %lfms\n", r, (double)(end - begin)/CLOCKS_PER_MSEC);
begin = clock();
if (!EC_ELGAMAL_mul(ctx1, c3, c2, 800))
goto err;
end = clock();
printf("EC_ELGAMAL_mul(C500,800) cost: %lfms\n", (double)(end - begin)/CLOCKS_PER_MSEC);
begin = clock();
if (!(EC_ELGAMAL_decrypt(ctx2, &r, c3)))
goto err;
end = clock();
printf("EC_ELGAMAL_decrypt(C500,800) result: %d, cost: %lfms\n", r, (double)(end - begin)/CLOCKS_PER_MSEC);
printf("EC_ELGAMAL_CIPHERTEXT_encode size: %zu\n", EC_ELGAMAL_CIPHERTEXT_encode(ctx2, NULL, 0, NULL, 1));
ret = 0;
err:
EC_KEY_free(sk_eckey);
EC_KEY_free(pk_eckey);
EC_ELGAMAL_DECRYPT_TABLE_free(table);
EC_ELGAMAL_CIPHERTEXT_free(c1);
EC_ELGAMAL_CIPHERTEXT_free(c2);
EC_ELGAMAL_CIPHERTEXT_free(c3);
EC_ELGAMAL_CTX_free(ctx1);
EC_ELGAMAL_CTX_free(ctx2);
fclose(sk_file);
fclose(pk_file);
return ret;
}
gcc编译
gcc -Wall -g -o ec_elgamal_test ./ec_elgamal_test.c -I/opt/tongsuo/include -L/opt/tongsuo/lib -lssl -lcrypto
运行结果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~