实验一 密码引擎-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;
}
posted @ 2022-04-17 22:49  WangYuHan20191323  阅读(150)  评论(0编辑  收藏  举报