ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-05-19 15:35:20  阅读:184  来源: 互联网

标签:PKEY const OpenSSL len char 引擎 key EVP OpenEuler


任务详情

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

加分项:在Windows中重现

在ubuntu编写代码测试openssl功能

base64测试

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/x509.h>

void tEVP_Encode()
{
	EVP_ENCODE_CTX *ctx;
        ctx = EVP_ENCODE_CTX_new();	
	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);
	printf("file\"Test.dat\" after Base64 coding:\n");

	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("file \"Test.dat\" Base64 coding is finish,save to \"test.txt\"文件.\n\n\n");
}

void tEVP_Decode()
{
	EVP_ENCODE_CTX *ctx;
        ctx = EVP_ENCODE_CTX_new();			
	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);
	printf("start file \"Test.txt\" Base64 decoding...\n\n");

	while(1)
	{
		inl = fread(in,1,1024,infp);
		if(inl <= 0)
			break;
		EVP_DecodeUpdate(ctx,out,&outl,in,inl);
		fwrite(out,1,outl,outfp);
	} 
	EVP_DecodeFinal(ctx,out,&outl);
	fwrite(out,1,outl,outfp);
	fclose(infp);
	fclose(outfp);	
	printf("file \"Test.txt\" Base64 decoding is finish,save as \"test-1.dat\"\n\n\n");
	
}
 
int main()
{
 
	tEVP_Encode();
	tEVP_Decode();
	
	return 0;
}

编译:gcc -o testbase64 testbase64.c -I /home/wpy/Desktop/20191317/include -L /home/wpy/Desktop/20191317/lib64 -lcrypto -lpthread

image-20220409190031586

运行:

image-20220409190054898

sm2测试

  • 生成公私钥对

    image-20220409193304040

  • 运行

    image-20220410123725150

// sm2_enc.c
#include <evp.h>
#include <pem.h>
#include <stdio.h>
#include <string.h>

/**
 * @brief 生成SM2公钥和私钥文件
 *
 * @param pri_file 私钥文件名
 * @param pub_file 公钥文件名
 * @return int 成功返回0,否则返回-1
 */
int gen_key(const char* pri_file, const char* pub_file);

/**
 * @brief 从文件中读取秘钥。
 *
 * @param key_file 公钥或私钥文件名
 * @param type 0读取公钥,1读取私钥
 * @return EVP_PKEY* 成功返回相应的秘钥,失败返回NULL
 */
EVP_PKEY* read_key_bio(const char* key_file, const int type);

/**
 * @brief 加密数据
 *
 * @param key 加密公钥
 * @param out 加密密文
 * @param in 要加密的数据
 * @param inlen 数据长度
 * @return size_t 密文长度
 */
size_t do_encrypt(EVP_PKEY* key, unsigned char* out, const unsigned char* in,
                  size_t inlen);

/**
 * @brief 解密数据
 *
 * @param key 解密私钥
 * @param out 解密后的数据
 * @param in 要解密的数据
 * @param inlen 数据长度
 * @return size_t 解密后的数据长度
 */
size_t do_decrypt(EVP_PKEY* key, unsigned char* out, const unsigned char* in,
                  size_t inlen);

int main(int argc, char const* argv[])
{
    size_t ret;

    const char* pub_file = "/home/wpy/Desktop/openssl_1/test_sm2_pub_key.pem";
    const char* pri_file = "/home/wpy/Desktop/openssl_1/test_sm2_pri.pem";
    // 生成公钥和私钥并写入文件中
    if (gen_key(pri_file, pub_file)) {
        printf("gen key failed.");
        exit(1);
    }
    // 读取公钥和私钥
    EVP_PKEY* pub_key = read_key_bio(pub_file, 0);
    EVP_PKEY* pri_key = read_key_bio(pri_file, 1);

    unsigned char data[]= "hello 20191317wpy!";
    unsigned char enc_txt[BUFSIZ] = {0};
    unsigned char dec_txt[BUFSIZ] = {0};
    printf("data= %s\n", data);

    // 公钥加密
    ret = do_encrypt(pub_key, enc_txt, data, strlen((const char*)data));
    printf("ret=%ld, enc= ", ret);
    for (size_t i = 0; i < ret; i++){
        printf("%2X", enc_txt[i]);
    }
    
    // 私钥解密
    ret = do_decrypt(pri_key, dec_txt, enc_txt, ret);
    dec_txt[ret] = 0;
    printf("\nret=%ld, dec= %s\n", ret, dec_txt);

    EVP_PKEY_free(pub_key);
    EVP_PKEY_free(pri_key);
    return 0;
}

int gen_key(const char* pri_file, const char* pub_file)
{
    EC_KEY* eckey = EC_KEY_new_by_curve_name(NID_sm2);

    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_sm2);
    EC_KEY_set_group(eckey, group);

    BIO* param = BIO_new_file("/tmp/param.cache", "w");
    PEM_write_bio_ECPKParameters(param, group);

    EC_KEY_generate_key(eckey);

    BIO* prikey = BIO_new_file(pri_file, "w");
    BIO* pubkey = BIO_new_file(pub_file, "w");

    PEM_write_bio_ECPrivateKey(prikey, eckey, NULL, NULL, 0, NULL, NULL);
    PEM_write_bio_EC_PUBKEY(pubkey, eckey);

    BIO_free(param);
    BIO_free(prikey);
    BIO_free(pubkey);
    return 0;
}

EVP_PKEY* read_key_bio(const char* key_file, const int type)
{
    BIO* bio = BIO_new_file(key_file, "r");

    EVP_PKEY* key = EVP_PKEY_new();
    if (0 == type) {
        key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
    } else {
        key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
    }

    EVP_PKEY_set_alias_type(key, EVP_PKEY_SM2);
    BIO_free(bio);
    return key;
}

size_t do_encrypt(EVP_PKEY* key, unsigned char* out, const unsigned char* in,
                  size_t inlen)
{
    size_t ret        = 0;
    EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(key, NULL);
    EVP_PKEY_encrypt_init(ctx);
    EVP_PKEY_encrypt(ctx, out, &ret, in, inlen);
    EVP_PKEY_CTX_free(ctx);
    return ret;
}

size_t do_decrypt(EVP_PKEY* key, unsigned char* out, const unsigned char* in,
                  size_t inlen)
{
    size_t ret        = inlen;
    EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(key, NULL);
    EVP_PKEY_decrypt_init(ctx);
    EVP_PKEY_decrypt(ctx, out, &ret, in, inlen);
    EVP_PKEY_CTX_free(ctx);
    return ret;
}

sm3测试

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/evp.h>

void tDigest()
{
    unsigned char md_value[EVP_MAX_MD_SIZE];
    int md_len, i;
    EVP_MD_CTX *mdctx;
    char msg1[] = "20191317wpy";
    char msg2[] = "wpy20191317";
    mdctx = EVP_MD_CTX_new();
    EVP_MD_CTX_init(mdctx);

    EVP_DigestInit_ex(mdctx, EVP_sm3(), NULL);
    EVP_DigestUpdate(mdctx, msg2, strlen(msg2));
    EVP_DigestFinal_ex(mdctx, md_value, &md_len);
    EVP_MD_CTX_free(mdctx);

    printf("原始数据%s的摘要值为:\n",msg2);
    for ( i = 0; i < md_len; i++)
    {
        printf("0x%02x ", md_value[i]);
    }
    printf("\n");
}

int main()
{
    OpenSSL_add_all_algorithms();
    tDigest();
    return 0;
}
  • 编译运行:

    image-20220410124105359

sm4测试

/** 文件名: https://github.com/liuqun/openssl-sm4-demo/blob/cmake/src/main.c */
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "openssl/err.h"
#include "openssl/evp.h"
 
/* Before OpenSSL 1.1.1-pre1, we did not have EVP_sm4_ofb() */
#if defined(OPENSSL_VERSION_NUMBER) \
    && OPENSSL_VERSION_NUMBER < 0x10101001L
static const EVP_CIPHER *(*EVP_sm4_ofb)()=EVP_aes_128_ecb;
#endif
 
typedef struct {
    const unsigned char *in_data;
    size_t in_data_len;
    int in_data_is_already_padded;
    const unsigned char *in_ivec;
    const unsigned char *in_key;
    size_t in_key_len;
} test_case_t;
 
 
void test_encrypt_with_cipher(const test_case_t *in, const EVP_CIPHER *cipher)
{
    unsigned char *out_buf = NULL;
    int out_len;
    int out_padding_len;
    EVP_CIPHER_CTX *ctx;
 
    ctx = EVP_CIPHER_CTX_new();
    EVP_EncryptInit_ex(ctx, cipher, NULL, in->in_key, in->in_ivec);
 
    if (in->in_data_is_already_padded)
    {
        /* Check whether the input data is already padded.
        And its length must be an integral multiple of the cipher's block size. */
        const size_t bs = EVP_CIPHER_block_size(cipher);
        if (in->in_data_len % bs != 0)
        {
            printf("ERROR-1: data length=%d which is not added yet; block size=%d\n", (int) in->in_data_len, (int) bs);
            /* Warning: Remember to do some clean-ups */
            EVP_CIPHER_CTX_free(ctx);
            return;
        }
        /* Disable the implicit PKCS#7 padding defined in EVP_CIPHER */
        EVP_CIPHER_CTX_set_padding(ctx, 0);
    }
 
    out_buf = (unsigned char *) malloc(((in->in_data_len>>4)+1) << 4);
    out_len = 0;
    EVP_EncryptUpdate(ctx, out_buf, &out_len, in->in_data, in->in_data_len);
    if (1)
    {
        printf("Debug: out_len=%d\n", out_len);
    }
 
    out_padding_len = 0;
    EVP_EncryptFinal_ex(ctx, out_buf+out_len, &out_padding_len);
    if (1)
    {
        printf("Debug: out_padding_len=%d\n", out_padding_len);
    }
 
    EVP_CIPHER_CTX_free(ctx);
    if (1)
    {
        int i;
        int len;
        len = out_len + out_padding_len;
        for (i=0; i<len; i++)
        {
            printf("%02x ", out_buf[i]);
        }
        printf("\n");
    }
 
    if (out_buf)
    {
        free(out_buf);
        out_buf = NULL;
    }
}
 
void main()
{
    int have_sm4 = (OPENSSL_VERSION_NUMBER >= 0x10101001L);
    int have_aes = 1;
    const unsigned char data[]=
    {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
    };
    unsigned char ivec[EVP_MAX_IV_LENGTH]; ///< IV 向量
    const unsigned char key1[16] = ///< key_data, 密钥内容, 至少16字节
    {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
    };
    test_case_t tc;
 
    tc.in_data = data;
    tc.in_data_len = sizeof(data);
    tc.in_data_is_already_padded = (tc.in_data_len % 16)==0; // Hard coded 16 as the cipher's block size
    tc.in_key = key1;
    tc.in_key_len = sizeof(key1);
    memset(ivec, 0x00, EVP_MAX_IV_LENGTH);
    tc.in_ivec = ivec;
 
#if defined(OPENSSL_NO_SM4)
    have_sm4 = 0;
#endif
    if (have_sm4)
    {
        printf("[1]\n");
        printf("Debug: EVP_sm4_ofb() test\n");
        test_encrypt_with_cipher(&tc, EVP_sm4_ofb());
    }
#if defined(OPENSSL_NO_AES)
    have_aes = 0;
#endif
    if (have_aes)
    {
        printf("[2]\n");
        printf("Debug: EVP_aes_128_ecb() test\n");
        test_encrypt_with_cipher(&tc, EVP_aes_128_ecb());
    }
}
  • 编译运行

    image-20220410124643045

openeuler下编译运行openssl测试代码

base64

image-20220410130505375

sm3

image-20220410134106408

sm4

image-20220410134137510

windows下的openssl测试代码运行

base64

gcc -o testsm4 testsm4.c -I /usr/local/openssl/include -L /usr/local/openssl/lib64 -lcrypto -lpthread

image-20220410135437827

sm3

image-20220410135859595

sm4

image-20220410135933634

标签:PKEY,const,OpenSSL,len,char,引擎,key,EVP,OpenEuler
来源: https://www.cnblogs.com/wpy-1049363419/p/16288661.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有