• 实验一密码引擎加密API实现与测试


    • 实现 GM/T 0018-2012 密码设备应用接口规范中部分接口函数。
    • 以 SDF_ExternalEncrypt_ECC、 SDF_HashUpdate 等为例。
    // sdf.h
    
    int SDF_ExternalEncrypt_ECC(
    		void* hSessionHandle,
    		unsigned int uiAlgID,
    		ECCrefPublicKey* pucPublicKey,
    		unsigned char* pucData,
    		unsigned int  uiDataLength,
    		ECCCipher* pucEncData
    	);
    
    int SDF_ExternalDecrypt_ECC(
    		void* hSessionHandle,
    		unsigned int uiAlgID,
    		ECCrefPrivateKey* pucPrivateKey,
    		ECCCipher* pucEncData,
    		unsigned char* pucData,
    		unsigned int* puiDataLength
    	);
    
    int SDF_HashInit(void* hSessionHandle,
    		unsigned int uiAlgID,
    		ECCrefPublicKey* pucPublicKey,
    		unsigned char* pucID,
    		unsigned int uiIDLength);
    
    int SDF_HashUpdate(void* hSessionHandle,
    		unsigned char* pucData,
    		unsigned int uiDataLength);
    
    int SDF_HashFinal(void* hSessionHandle,
    		unsigned char* pucHash,
    		unsigned int* puiHashLength);
    

    调用 OpenSSL 接口来封装上述函数。

    // sdf.c
    
    int SDF_ExternalEncrypt_ECC(void* hSessionHandle, unsigned int uiAlgID, ECCrefPublicKey* pucPublicKey, unsigned char* pucData, unsigned int uiDataLength, ECCCipher* pucEncData)
    {
    	if (uiDataLength > 32) {
    		printf("Too much bytes for pucData!\n");
    		return SDR_PKOPERR;
    	}
    	int error_code;
    	unsigned char c1[65], c3[32];
    	unsigned char* c2;
    	int i;
    	unsigned char pub_key[65] = { 0x04 };
    	for (i = 1; i < 33; i++) {
    		pub_key[i] = pucPublicKey->x[i-1];
    	}
    	for (i = 33; i < 65; i++) {
    		pub_key[i] = pucPublicKey->y[i-33];
    	}
    	
    	if (!(c2 = (unsigned char*)malloc(uiDataLength)))
    	{
    		printf("Memory allocation failed!\n");
    		return SDR_NOBUFFER;
    	}
    	if (error_code = sm2_encrypt(pucData, uiDataLength, pub_key, c1, c3, c2)) {
    		printf("Create SM2 ciphertext by using input defined in standard failed!\n");
    		free(c2);
    		return SDR_PKOPERR;
    	}
    	for (i = 0; i < 32; i++) {
    		pucEncData->x[i] = c1[i+1];
    	}
    	for (i = 0; i < 32; i++) {
    		pucEncData->y[i] = c1[i+33];
    	}
    	for (i = 0; i < uiDataLength; i++) {
    		pucEncData->C[i] = c2[i];
    	}
    	for (i = uiDataLength; i < 32; i++) {
    		pucEncData->C[i] = 0x00;
    	}
    	for (i = 0; i < 32; i++) {
    		pucEncData->M[i] = c3[i];
    	}
    	return SDR_OK;
    }
    
    // sdf.h
    
    int SDF_HashInit(void* hSessionHandle,
    		unsigned int uiAlgID,
    		ECCrefPublicKey* pucPublicKey,
    		unsigned char* pucID,
    		unsigned int uiIDLength);
    
    int SDF_HashUpdate(void* hSessionHandle,
    		unsigned char* pucData,
    		unsigned int uiDataLength);
    
    int SDF_HashFinal(void* hSessionHandle,
    		unsigned char* pucHash,
    		unsigned int* puiHashLength);
    
    // sdf.c
    
    int SDF_HashInit(void* hSessionHandle, unsigned int uiAlgID,
     ECCrefPublicKey* pucPublicKey, unsigned char* pucID, unsigned int uiIDLength) {
    	
    	EVP_MD_CTX* md_ctx = EVP_MD_CTX_new();
    	const EVP_MD* md = EVP_sm3();
    	EVP_DigestInit_ex(md_ctx, md, NULL);
    	
    	return SDR_OK;
    	
    }
    
    int SDF_HashUpdate(void* hSessionHandle, unsigned char* pucData, unsigned int uiDataLength) {
    	
    	EVP_DigestUpdate(md_ctx, pucData, uiDataLength);
    
    	return SDR_OK;
    
    }
    
    int SDF_HashFinal(void* hSessionHandle, unsigned char* pucHash, unsigned int* puiHashLength) {
    
    	EVP_DigestFinal_ex(md_ctx, pucHash, puiHashLength);
    	EVP_MD_CTX_free(md_ctx);
    	return SDR_OK;
    }
    
    • SDF 规范中与哈希运算相关的函数都可以直接调用 OpenSSL 中的接口,稍作修改即可完成。
    • 计算字符串“20191210”的散列值,与 OpenSSL 的计算结果一致。
  • 相关阅读:
    linux 回收站 路径
    Linux 让进程在后台可靠运行的几种方法
    用marquee和div+js实现首尾相连循环滚动效果
    轻型数据库SQLite结合PHP的开发
    linux系统权限修复——学生误操作!
    2009级 毕业设计 题目
    linux下硬盘uuid查看及修改设置
    创建网站地图
    用上下左右箭头键在textbox中的光标跳转
    SHELL中时间的比较
  • 原文地址:https://www.cnblogs.com/pogbar/p/16175291.html
Copyright © 2020-2023  润新知