课设第二周进展

本周计划完成的任务:

找到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
运行结果

gitee 链接:https://gitee.com/cloud-in/national-secret-store

posted @   20201303张奕博  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示