📄 inituser.c
字号:
//encryptfile.c 文件加密演示程序
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);
//--------------------------------------------------------------------
//加密算法和分组长度标识
#define ENCRYPT_ALGORITHM CALG_RC2
#define ENCRYPT_BLOCK_SIZE 8
//加密函数声明
static BOOL CryptEncryptFile(
PCHAR szSource, //明文文件名
PCHAR szDestination, //密文文件名
PCHAR szPassword//口令
);
//--------------------------------------------------------------------
void main(void)
{
PCHAR szSource;
PCHAR szDestination;
PCHAR szPassword;
int response;
//为明文文件名分配空间
if(!(szSource=(char *)malloc(100)))
HandleError("内存溢出");
//为密文文件名分配空间
if(!(szDestination=(char *)malloc(100)))
HandleError("内存溢出");
//为口令字分配空间
if(!(szPassword=(char *)malloc(100)))
HandleError("内存溢出");
printf("文件加密演示程序\n\n");
printf("请输入需要加密的文件名: ");
scanf("%s",szSource);
printf("请输入输出(密文)文件名: ");
scanf("%s",szDestination);
printf("加密文件是否需要口令? ( y/n ) ");
response=_getche();
if(response == 'y')
{
printf("请输入口令:");
scanf("%s",szPassword);
}
else
{
printf("密钥的产生不需要口令\n");
free(szPassword);
szPassword = NULL;
}
//--------------------------------------------------------------------
//调用CryptEncryptFile函数完成实际加密操作
if(CryptEncryptFile(szSource, szDestination, szPassword))
{
printf("加密文件%s成功\n", szSource);
printf("加密好的数据在文件%s中\n",szDestination);
}
else
{
HandleError("加密文件错误!");
}
} // End of main
//--------------------------------------------------------------------
// 加密函数代码
BOOL CryptEncryptFile(
PCHAR szSource,
PCHAR szDestination,
PCHAR szPassword)
//--------------------------------------------------------------------
//函数参数包括:
// szSource:输入的明文文件名。
// szDestination:输出的加密好的文件名。
// szPassword:口令字符串,或者为空。
{
//--------------------------------------------------------------------
// 声明和初始化本地变量
FILE *hSource;
FILE *hDestination;
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTKEY hXchgKey;
HCRYPTHASH hHash;
PBYTE pbKeyBlob;
DWORD dwKeyBlobLen;
PBYTE pbBuffer;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;
//--------------------------------------------------------------------
//打开需要加密的明文文件
if(hSource = fopen(szSource,"rb"))
{
printf("明文文件, %s, 被打开\n", szSource);
}
else
{
HandleError("打开明文文件出错!");
}
//--------------------------------------------------------------------
// 打开存放密文的文件
if(hDestination = fopen(szDestination,"wb"))
{
printf("密文文件,%s,被打开\n", szDestination);
}
else
{
HandleError("打开密文文件的时候出错!");
}
//获取默认CSP句柄
if(CryptAcquireContext(
&hCryptProv,
NULL,
NULL,
PROV_RSA_FULL,
0))
{
printf("已经获得CSP句柄\n");
}
else
{
HandleError("调用CryptAcquireContext函数时出错!");
}
//--------------------------------------------------------------------
//创建会话密钥
if(!szPassword )
{
//如果没有口令,则使用一个随机会话密钥加密文件,并把密钥写到文件中。
//---------------------------------------------------------------
//创建随机会话密钥
if(CryptGenKey(
hCryptProv,
ENCRYPT_ALGORITHM,
CRYPT_EXPORTABLE,
&hKey))
{
printf("已经产生会话密钥\n");
}
else
{
HandleError("调用CryptGenKey函数时出错\n");
}
//---------------------------------------------------------------
//取得加密这交换公钥句柄
if(CryptGetUserKey(
hCryptProv,
AT_KEYEXCHANGE,
&hXchgKey))
{
printf("用户公钥已获取\n");
}
else
{
HandleError("用户公钥不存在");
}
//---------------------------------------------------------------
//判断密钥块大小,并为其分配内存。
if(CryptExportKey(
hKey,
hXchgKey,
SIMPLEBLOB,
0,
NULL,
&dwKeyBlobLen))
{
printf("密钥块为%d个字节长\n",dwKeyBlobLen);
}
else
{
HandleError("计算密钥块长度时出错! \n");
}
if(pbKeyBlob =(BYTE *)malloc(dwKeyBlobLen))
{
printf("已经为密钥块分配内存\n");
}
else
{
HandleError("内存溢出!\n");
}
//---------------------------------------------------------------
//加密并把会话密钥输出到简单密钥块中。
if(CryptExportKey(
hKey,
hXchgKey,
SIMPLEBLOB,
0,
pbKeyBlob,
&dwKeyBlobLen))
{
printf("密钥块已输出\n");
}
else
{
HandleError("调用CryptExportKey函数时出错!\n");
}
//---------------------------------------------------------------
//释放密钥交换密钥句柄
CryptDestroyKey(hXchgKey);
hXchgKey = 0;
//---------------------------------------------------------------
//把密钥块大小写进加密好的文件
fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination);
if(ferror(hDestination))
{
HandleError("写密文文件头时出错");
}
else
{
printf("文件头已写好\n");
}
//--------------------------------------------------------------
//把密钥块写到密文文件中。
fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination);
if(ferror(hDestination))
{
HandleError("写密文文件头出错");
}
else
{
printf("密钥块已被写到密文文件中\n");
}
}
else
{
//--------------------------------------------------------------------
//文件将使用从口令得到的会话密钥进行加密。
// 当文件解密时将根据同样的口令产生同样的会话密钥来解密。
//--------------------------------------------------------------------
//创建哈希对象
if(CryptCreateHash(
hCryptProv,
CALG_MD5,
0,
0,
&hHash))
{
printf("哈希对象已创建\n");
}
else
{
HandleError("调用CryptCreateHash函数时出错!\n");
}
//--------------------------------------------------------------------
//对口令进行哈希
if(CryptHashData(
hHash,
(BYTE *)szPassword,
strlen(szPassword),
0))
{
printf("口令已增加到哈希对象中\n");
}
else
{
HandleError("调用CryptHashData函数时出错\n");
}
//--------------------------------------------------------------------
//从哈希对象获取会话密钥
if(CryptDeriveKey(
hCryptProv,
ENCRYPT_ALGORITHM,
hHash,
0,
&hKey))
{
printf("加密密钥已经从口令哈希对象中获取\n");
}
else
{
HandleError("调用CryptDeriveKey函数时出错!\n");
}
//--------------------------------------------------------------------
//销毁哈希对象
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;
//--------------------------------------------------------------------
//分配内存
if(pbBuffer = (BYTE *)malloc(dwBufferLen))
{
printf("缓冲区内存已分配\n");
}
else
{
HandleError("内存溢出\n");
}
//--------------------------------------------------------------------
//循环加密文件
do
{
dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
if(ferror(hSource))
{
HandleError("读取明文失败!\n");
}
//加密数据。
if(!CryptEncrypt(
hKey,
0,
feof(hSource),
0,
pbBuffer,
&dwCount,
dwBufferLen))
{
HandleError("调用CryptEncrypt函数出错\n");
}
//--------------------------------------------------------------------
//把加密好的数据写到密文文件
fwrite(pbBuffer, 1, dwCount, hDestination);
if(ferror(hDestination))
{
HandleError("写密文失败");
}
}
while(!feof(hSource));
//当最后一个明文块加密之后退出循环
//关闭文件
if(hSource)
fclose(hSource);
if(hDestination)
fclose(hDestination);
//释放内存
if(pbBuffer)
free(pbBuffer);
//销毁会话密钥
if(hKey)
CryptDestroyKey(hKey);
//释放密钥交换密钥句柄
if(hXchgKey)
CryptDestroyKey(hXchgKey);
//销毁哈希对象
if(hHash)
CryptDestroyHash(hHash);
//释放CSP句柄
if(hCryptProv)
CryptReleaseContext(hCryptProv, 0);
return(TRUE);
}
//错误处理函数
void HandleError(char *s)
{
printf("在运行程序时出现错误\n");
printf("%s\n",s);
printf("错误代号 %x\n.",GetLastError());
printf("程序终止运行\n");
exit(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -