• 实验一 密码引擎4国密算法交叉测试


    实验一 密码引擎-4-国密算法交叉测试

    在Ubuntu中使用OpenSSL用SM4算法加密上述文件,然后用龙脉eKey解密,提交代码和运行结果截图

    openssl加密

    UKEY解密

    OPENSSL代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <openssl/err.h>
    #include <openssl/objects.h>
    #include <openssl/evp.h>
    #include <openssl/err.h>
    #include <openssl/rand.h>
    
    int main(int argc, char *argv[])
    {
    	int rv;
    	unsigned char Buffer[4096];			//保存待处理的文件数据的数组
    	unsigned char SessionKey[16];		//加密发送文件的会话密钥
    	unsigned int SessionKeyLen = 16;	//会话密钥的密文长度						
    	unsigned char err[1024];
    	OpenSSL_add_all_algorithms();
    	//产生随机数,作为会话密钥
    	RAND_bytes(SessionKey,16);
    	//利用会话密钥加密原文,并输出到密文到文件
    	FILE *fpIn;
    	FILE *fpOut;
    	fpIn = fopen(argv[1],"rb");
    	if(fpIn == NULL)
    	{
    		return 0;
    	}
    
    	fpOut = fopen(argv[2],"wb");
    	if(fpOut == NULL)
    	{
    		return 0;
    	}
    
    	//密文文件格式:
    	// |------------------|--------|------------------------|------------|--------------
    	// |签名信息长度4Bytes|签名信息|会话密钥的密文长度4Bytes|会话密钥密文|原文数据的密文
    	fwrite(&SessionKeyLen,1,sizeof(SessionKeyLen),fpOut);	//写密文的会话密钥的长度到文件
    	fwrite(SessionKey,1,SessionKeyLen,fpOut);//写密文的会话密钥到文件
    	EVP_CIPHER_CTX *ctx;
    	ctx = EVP_CIPHER_CTX_new();
    	unsigned char out[1024];
    	int outl;
    	unsigned char in[1024];
    	int inl;
    	EVP_CIPHER_CTX_init(ctx);//初始化密码算法上下文
    	//设置密码算法和密钥,这里采用128位的sm4算法。
    	rv = EVP_EncryptInit_ex(ctx,EVP_sm4_ecb(),NULL,SessionKey,NULL);
    	if(rv != 1)
    	{
    		EVP_CIPHER_CTX_free(ctx);
    		return 0;
    	}
    	//以1024字节为单位,循环读取原文,并加密,然后输出到密文文件。
    	for(;;)
    	{
    		inl = fread(in,1,1024,fpIn);//读取1024字节
    		if(inl <= 0)
    			break;
    		rv = EVP_EncryptUpdate(ctx,out,&outl,in,inl);//加密
    		if(rv != 1)
    		{
    			fclose(fpIn);
    			fclose(fpOut);
    			EVP_CIPHER_CTX_free(ctx);
    			return 0;
    		}
    		fwrite(out,1,outl,fpOut);//输出密文到文件
    	}
    	rv = EVP_EncryptFinal_ex(ctx,out,&outl);//完成加密,输出剩余的密文。
    	if(rv != 1)
    	{
    		fclose(fpIn);
    		fclose(fpOut);
    		EVP_CIPHER_CTX_cleanup(ctx);
    		return 0;
    	}
    	fwrite(out,1,outl,fpOut);//写文件
    	fclose(fpIn);
    	fclose(fpOut);
    	EVP_CIPHER_CTX_free(ctx);
    	return 0;
    }
    

    UKEY代码

    #include "../include/skfapi.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define	TRUE	1
    #define FALSE	0
    #define ERROR_THROW(r) {if((r) != SAR_OK) goto END_OF_FUN;}
    
    
    int main(int argc, char* argv[])
    {
    	ULONG ulRslt = SAR_OK;
    	HANDLE hdev = NULL;
    	HANDLE happ = NULL;
    	HANDLE hkey = NULL;
    	HANDLE hcont = NULL;
    	char   szDevName[256] = {0};
    	ULONG	ulDevNameLen = 256;
    	char	szAppName[256] = {0};
    	ULONG	ulAppNameLen = 256;
    	char	szContName[256] = {0};
    	ULONG	ulContName = 256;
    	char	*pUserPin = "12345678";
    	ULONG	ulRetryCount = 0;
    	BYTE SessionKey[16];		//会话密钥
    	unsigned int SessionKeyLen;			//会话密钥长度
    	BYTE	pbEncrypt[256] = {0};
    	ULONG   ulEncryptLen = 256;
    	BLOCKCIPHERPARAM bp = {0};
    	int  nDatalen = strlen(pData);
    	char *pContName = szContName;
    	char *pdevname = szDevName;
    	char *pappname = szAppName;
    
    	ulRslt = SKF_EnumDev(TRUE, szDevName, &ulDevNameLen);
    	ERROR_THROW(ulRslt)
    
    	
    	ulRslt = SKF_ConnectDev(pdevname, &hdev);
    	ERROR_THROW(ulRslt)
    
    	ulRslt = SKF_EnumApplication(hdev, szAppName, &ulAppNameLen);
    	ERROR_THROW(ulRslt)
    
    	
    	ulRslt = SKF_OpenApplication(hdev, pappname, &happ);
    	ERROR_THROW(ulRslt)
    
    	ulRslt = SKF_VerifyPIN(happ, USER_TYPE, pUserPin, &ulRetryCount);
    	ERROR_THROW(ulRslt)
    
    	ulRslt = SKF_EnumContainer(happ, szContName, &ulContName);
    	ERROR_THROW(ulRslt)
    
    	
    	ulRslt = SKF_OpenContainer(happ, pContName, &hcont);
    	ERROR_THROW(ulRslt)
        //根据安全报文的文件格式,读取安全报文
    	//--------------------|--------|--------------
    	//会话密钥的长度4Bytes|会话密钥|原文数据的密文
    	//密文Sessionkey
    	FILE* fp = fopen(argv[1],"rb");
    	FILE *fpOut = fopen(argv[2],"wb");
    	if(fp == NULL)
    	{
    	    fprintf(stderr,"打开加密文件失败\n");
    		goto END_OF_FUN;
    	}
    	if(fpOut==NULL)
    	{
    	    fprintf(stderr,"打开解密文件失败!");
    		fclose(fp);
    		goto END_OF_FUN;
    	}
    	fread(&SessionKeyLen,1,sizeof(SessionKeyLen),fp);
    	printf("%d",SessionKeyLen);
    	if((SessionKeyLen<=0)||(SessionKeyLen >18))
    	{
    	    fprintf(stderr,"读取会话密钥错误!");
    		fclose(fp);
    		goto END_OF_FUN;
    	}
    	fread(SessionKey,1,SessionKeyLen,fp);
    	
    	ulRslt = SKF_SetSymmKey(hdev, SessionKey, SGD_SM4_ECB, &hkey);
    	ERROR_THROW(ulRslt)
    
    	bp.PaddingType = 1;
    	ulRslt = SKF_DecryptInit(hkey, bp);
    	ERROR_THROW(ulRslt)
    	//利用明文的会话密钥解密安全报文
    	BYTE out[1024];
    	INT32 outl;
    	BYTE in[1024];
    	INT32 inl;
    	for( ; ; )
    	{
    		inl = fread(in,1,1024,fp);//读取1024个字节
    		if(inl <= 0)
    			break;
    		ulRslt = SKF_DecryptUpdate(hkey,in, inl,out, &outl);
    		if(ulRslt != SAR_OK)
    		{
    			fclose(fp);
    			fclose(fpOut);
    			goto END_OF_FUN;
    		}
    		fwrite(out,1,outl,fpOut);
    	}
    	ulRslt = SKF_DecryptFinal(hkey, out, &outl);
    	if(ulRslt != SAR_OK)
    		{
    			fclose(fp);
    			fclose(fpOut);
    			goto END_OF_FUN;
    		}
    	fwrite(out,1,outl,fpOut);
    	printf("解密成功!");
    	fclose(fp);
    	fclose(fpOut);
    END_OF_FUN:
    	printf("%x\n",ulRslt);
    	if(hkey)
    		SKF_CloseHandle(hkey);
    	if(hcont)
    		SKF_CloseContainer(hcont);
    	if(happ)
    		SKF_CloseApplication(happ);
    	if(hdev)
    		SKF_DisConnectDev(hdev);
    	return 1;
    }
    
  • 相关阅读:
    快速开发框架:进销存业务注意事项
    延时执行函数:前浪死在沙滩上
    新增筛选方案
    进销存数据库设计:采购订单
    SasS 设计原则十二因素
    四种线程池的解析
    高并发下的流量控制
    Mybatis 缓存机制
    谈谈JVM垃圾回收
    如何使错误日志更加方便地排查问题
  • 原文地址:https://www.cnblogs.com/WANGYUHAN/p/16157776.html
Copyright © 2020-2023  润新知