用CryptoAPI进行数据加密.docx

上传人:b****8 文档编号:29592636 上传时间:2023-07-24 格式:DOCX 页数:9 大小:18.05KB
下载 相关 举报
用CryptoAPI进行数据加密.docx_第1页
第1页 / 共9页
用CryptoAPI进行数据加密.docx_第2页
第2页 / 共9页
用CryptoAPI进行数据加密.docx_第3页
第3页 / 共9页
用CryptoAPI进行数据加密.docx_第4页
第4页 / 共9页
用CryptoAPI进行数据加密.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

用CryptoAPI进行数据加密.docx

《用CryptoAPI进行数据加密.docx》由会员分享,可在线阅读,更多相关《用CryptoAPI进行数据加密.docx(9页珍藏版)》请在冰豆网上搜索。

用CryptoAPI进行数据加密.docx

用CryptoAPI进行数据加密

用CryptoAPI进行数据加密

南京理工大学计算机系胡静李蔚清

由于过于复杂的加密算法实现起来非常困难,所以在过去,许多应用程序只能使用非常简单的加密技术,这样做的结果就是加密的数据很容易被人破译。

而使用Microsoft提供的加密应用程序接口(即CryptographyAPI),或称CryptoAPI,可以方便地在应用程序中加入强大的加密功能,而不必考虑基本的算法。

本文将对CryptoAPI及其使用的数据加密原理作一简单的介绍,然后给出了用CryptoAPI编写加密程序的大致步骤,最后以一个文件的加密、解密程序为例演示CryptoAPI的部分功能。

1.CryptoAPI简介

CryptoAPI是一组函数,为了完成数学计算,必须具有密码服务提供者模块(CSP)。

Microsoft通过捆绑RSABaseProvider在操作系统级提供一个CSP,使用RSA公司的公钥加密算法,更多的CSP可以根据需要增加到应用中。

事实上,CSP有可能与特殊硬件设备(如智能卡)一起来进行数据加密。

CryptoAPI接口允许简单的函数调用来加密数据,交换公钥,散列一个消息来建立摘要以及生成数字签名。

它还提供高级的管理操作,如从一组可能的CSP中使用一个CSP。

此外,CryptoAPI还为许多高级安全性服务提供了基础,包括用于电子商务的SET,用于加密客户机/服务器消息的PCT,用于在各个平台之间来回传递机密数据和密钥的PFX,代码签名等等。

CryptoAPI的体系结构如图1。

图1CryptoAPI体系结构

目前支持CryptoAPI的Windows系统有:

Windows95OSR2、WindowsNTSP3及后续版本、Windows98、Windows2000等。

CryptoAPI的配置信息存储在注册表中,包括如下密钥:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults

HKEY_CURRENT_USER\Software\Microsoft\Cryptography\Providers

2.数据加密原理

数据加密流程如图2所示。

图2数据加密流程

CryptoAPI使用两种密钥:

会话密钥与公共/私人密钥对。

会话密钥使用相同的加密和解密密钥,这种算法较快,但必须保证密钥的安全传递。

公共/私人密钥对使用一个公共密钥和一个私人密钥,私人密钥只有专人才能使用,公共密钥可以广泛传播。

如果密钥对中的一个用于加密,另一个一定用于解密。

公共/私人密钥对算法很慢,一般只用于加密小批量数据,例如用于加密会话密钥。

CryptoAPI支持两种基本的编码方法:

流式编码和块编码。

流式编码在明码文本的每一位上创建编码位,速度较快,但安全性较低。

块编码在一个完整的块上(一般为64位)工作,需要使用填充的方法对要编码的数据进行舍入,以组成多个完整的块。

这种算法速度较慢,但更安全。

3.应用举例

下面以两个文件加密与解密的C程序片断为例,演示一下CryptoAPI的强大功能。

这两个程序均为Win32控制台应用,程序省略了出错处理,实际运行时请加入。

1文件加密

#include

#include

#include

#include

//确定使用RC2块编码或是RC4流式编码

#ifdefUSE_BLOCK_CIPHER

#defineENCRYPT_ALGORITHMCALG_RC2

#defineENCRYPT_BLOCK_SIZE8

#else

#defineENCRYPT_ALGORITHMCALG_RC4

#defineENCRYPT_BLOCK_SIZE1

#endif

voidCAPIDecryptFile(PCHARszSource,PCHARszDestination,PCHARszPassword);

void_cdeclmain(intargc,char*argv[])

{

PCHARszSource=NULL;

PCHARszDestination=NULL;

PCHARszPassword=NULL;

//验证参数个数

if(argc!

=3&&argc!

=4){

printf("USAGE:

decrypt[]\n");

exit

(1);

}

//读取参数.

szSource=argv[1];

szDestination=argv[2];

if(argc==4){

szPassword=argv[3];

}

CAPIDecryptFile(szSource,szDestination,szPassword);

}

/*szSource为要加密的文件名称,szDestination为加密过的文件名称,szPassword为加密口令*/

voidCAPIEncryptFile(PCHARszSource,PCHARszDestination,PCHARszPassword){

FILE*hSource=NULL;

FILE*hDestination=NULL;

INTeof=0;

HCRYPTPROVhProv=0;

HCRYPTKEYhKey=0;

HCRYPTKEYhXchgKey=0;

HCRYPTHASHhHash=0;

PBYTEpbKeyBlob=NULL;

DWORDdwKeyBlobLen;

PBYTEpbBuffer=NULL;

DWORDdwBlockLen;

DWORDdwBufferLen;

DWORDdwCount;

hSource=fopen(szSource,"rb"));//打开源文件

hDestination=fopen(szDestination,"wb");//.打开目标文件

//连接缺省的CSP

CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,0));

if(szPassword==NULL){

//口令为空,使用随机产生的会话密钥加密

//产生随机会话密钥。

CryptGenKey(hProv,ENCRYPT_ALGORITHM,CRYPT_EXPORTABLE,&hKey)

//取得密钥交换对的公共密钥

CryptGetUserKey(hProv,AT_KEYEXCHANGE,&hXchgKey);

//计算隐码长度并分配缓冲区

CryptExportKey(hKey,hXchgKey,SIMPLEBLOB,0,NULL,&dwKeyBlobLen);

pbKeyBlob=malloc(dwKeyBlobLen))==NULL);

//将会话密钥输出至隐码

CryptExportKey(hKey,hXchgKey,SIMPLEBLOB,0,pbKeyBlob,&dwKeyBlobLen))

//释放密钥交换对的句柄

CryptDestroyKey(hXchgKey);

hXchgKey=0;

//将隐码长度写入目标文件

fwrite(&dwKeyBlobLen,sizeof(DWORD),1,hDestination);

//将隐码长度写入目标文件

fwrite(pbKeyBlob,1,dwKeyBlobLen,hDestination);

}else{

//口令不为空,使用从口令派生出的密钥加密文件

CryptCreateHash(hProv,CALG_MD5,0,0,&hHash);//建立散列表

CryptHashData(hHash,szPassword,

strlen(szPassword),0);//散列口令

//从散列表中派生密钥

CryptDeriveKey(hProv,ENCRYPT_ALGORITHM,hHash,0,&hKey);

//删除散列表

CryptDestroyHash(hHash);

hHash=0;

}

//计算一次加密的数据字节数,必须为ENCRYPT_BLOCK_SIZE的整数倍dwBlockLen=1000-1000%ENCRYPT_BLOCK_SIZE;

//如果使用块编码,则需要额外空间

if(ENCRYPT_BLOCK_SIZE>1){

dwBufferLen=dwBlockLen+ENCRYPT_BLOCK_SIZE;

}else{

dwBufferLen=dwBlockLen;

}

//分配缓冲区

pbBuffer=malloc(dwBufferLen);

//加密源文件并写入目标文件

do{

//从源文件中读出dwBlockLen个字节

dwCount=fread(pbBuffer,1,dwBlockLen,hSource);

eof=feof(hSource);

//加密数据

CryptEncrypt(hKey,0,eof,0,pbBuffer,&dwCount,dwBufferLen);

//将加密过的数据写入目标文件

fwrite(pbBuffer,1,dwCount,hDestination);

}while(!

feof(hSource));

printf("OK\n");

......//关闭文件、释放内存

}

2文件解密

voidCAPIDecryptFile(PCHARszSource,PCHARszDestination,PCHARszPassword)

{

......//变量声明、文件操作同文件加密程序

CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,0);

if(szPassword==NULL){

//口令为空,使用存储在加密文件中的会话密钥解密

//读隐码的长度并分配内存

fread(&dwKeyBlobLen,sizeof(DWORD),1,hSource);

pbKeyBlob=malloc(dwKeyBlobLen))==NULL);

//从源文件中读隐码.

fread(pbKeyBlob,1,dwKeyBlobLen,hSource);

//将隐码输入CSP

CryptImportKey(hProv,pbKeyBlob,dwKeyBlobLen,0,0,&hKey);

}else{

//口令不为空,使用从口令派生出的密钥解密文件

CryptCreateHash(hProv,CALG_MD5,0,0,&hHash);

CryptHashData(hHash,szPassword,strlen(szPassword),0);

CryptDeriveKey(hProv,ENCRYPT_ALGORITHM,hHash,0,&hKey);

CryptDestroyHash(hHash);

hHash=0;

}

dwBlockLen=1000-1000%ENCRYPT_BLOCK_SIZE;

if(ENCRYPT_BLOCK_SIZE>1){

dwBufferLen=dwBlockLen+ENCRYPT_BLOCK_SIZE;

}else{

dwBufferLen=dwBlockLen;

}

pbBuffer=malloc(dwBufferLen);

//解密源文件并写入目标文件

do{

dwCount=fread(pbBuffer,1,dwBlockLen,hSource);

eof=feof(hSource);

//解密数据

CryptDecrypt(hKey,0,eof,0,pbBuffer,&dwCount);

//将解密过的数据写入目标文件

fwrite(pbBuffer,1,dwCount,hDestination);

}while(!

feof(hSource));

printf("OK\n");

......//关闭文件、释放内存}

正文:

  给文件加密的技术很多,其中又分为不同等级,以适合不同场合的需要.这里给出最简单的文件加密技术,即采用文件逐字节与密码异或方式对

文件进行加密,当解密时,只需再运行一遍加密程序即可.

  下面是一个实例程序,能对任意一个文件进行加密,密码要求用户输入,限8位以内(当然你可以再更改).程序有很好的容错设计,这是我们应该

学习的.

/*Turbo2.0pass.givefileapassword!

*/

#include

#include

#include

#include

voiddofile(char*in_fname,char*pwd,char*out_fname);/*对文件进行加密的具体函数*/

voidmain(intargc,char*argv[])/*定义main()函数的命令行参数*/

{

charin_fname[30];/*用户输入的要加密的文件名*/

charout_fname[30];

charpwd[8];/*用来保存密码*/

if(argc!

=4){/*容错处理*/

printf("nIn-fname:

n");

gets(in_fname);/*得到要加密的文件名*/

printf("Password:

n");

gets(pwd);/*得到密码*/

printf("Out-file:

n");

gets(out_fname);/*得到加密后你要的文件名*/

dofile(in_fname,pwd,out_fname);

}

else{/*如果命令行参数正确,便直接运行程序*/

strcpy(in_fname,argv[1]);

strcpy(pwd,argv[2]);

strcpy(out_fname,argv[3]);

dofile(in_fname,pwd,out_fname);

}

}

/*加密子函数开始*/

voiddofile(char*in_fname,char*pwd,char*out_file)

{

FILE*fp1,*fp2;

registercharch;

intj=0;

intj0=0;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 制度规范

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1