📄 inituser.c
字号:
//decryptfile 文件解密演示程序
#include <stdio.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
// 解密函数声明
BOOL CryptDecryptFile(
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(CryptDecryptFile(szSource, szDestination, szPassword))
{
printf("解密文件%s成功\n", szSource);
printf("解密好的数据在文件%s中\n",szDestination);
}
else
{
HandleError("解密文件错误!");
}
} // End of main
//--------------------------------------------------------------------
//解密函数CryptDecryptFile定义。
static BOOL CryptDecryptFile(
PCHAR szSource,
PCHAR szDestination,
PCHAR szPassword)
{
//--------------------------------------------------------------------
//函数参数包括:
// szSource:输入的密文文件名。
// szDestination:输出的解密好的文件名。
// szPassword:口令字符串,或者为空。
{
//--------------------------------------------------------------------
// 声明和初始化本地变量
FILE *hSource;
FILE *hDestination;
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHash;
PBYTE pbKeyBlob = NULL;
DWORD dwKeyBlobLen;
PBYTE pbBuffer;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;
BOOL status = FALSE;
//--------------------------------------------------------------------
//打开需要解密的密文文件
if(!(hSource = fopen(szSource,"rb")))
{
HandleError("密文文件打开失败!");
}
//--------------------------------------------------------------------
//打开要存放明文的文件
if(!(hDestination = fopen(szDestination,"wb")))
{
HandleError("明文文件打开失败!");
}
//--------------------------------------------------------------------
//获取默认CSP句柄
if(!CryptAcquireContext(
&hCryptProv,
NULL,
NULL,
PROV_RSA_FULL,
0))
{
HandleError("调用CryptAcquireContext函数出错!");
}
//--------------------------------------------------------------------
// 检查口令是否存在
if(!szPassword) //如果不使用口令
{
//--------------------------------------------------------------------
//用存储的会话密钥解密文件
//从源文件(密文)中读取密钥块长度,并分配内存。
fread(&dwKeyBlobLen, sizeof(DWORD), 1, hSource);
if(ferror(hSource) || feof(hSource))
{
HandleError("文件头读取失败!");
}
if(!(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen)))
{
HandleError("内存分配错误");
}
//--------------------------------------------------------------------
//从源文件(密文)中读取密钥块。
fread(pbKeyBlob, 1, dwKeyBlobLen, hSource);
if(ferror(hSource) || feof(hSource))
{
HandleError("读取文件头失败\n");
}
//--------------------------------------------------------------------
//把密钥块输入到CSP中
if(!CryptImportKey(
hCryptProv,
pbKeyBlob,
dwKeyBlobLen,
0,
0,
&hKey))
{
HandleError("调用CryptImportKey函数失败!");
}
}
else
{
//从口令获取的会话密钥解密文件。
//创建哈希对象
if(!CryptCreateHash(
hCryptProv,
CALG_MD5,
0,
0,
&hHash))
{
HandleError("调用CryptCreateHash函数出错!");
}
//--------------------------------------------------------------------
//把口令增加到哈希对象
if(!CryptHashData(
hHash,
(BYTE *)szPassword,
strlen(szPassword),
0))
{
HandleError("调用CryptHashData函数出错!");
}
//--------------------------------------------------------------------
//从哈希对象获取会话密钥。
if(!CryptDeriveKey(
hCryptProv,
ENCRYPT_ALGORITHM,
hHash,
0,
&hKey))
{
HandleError("调用CryptDeriveKey函数失败!");
}
//--------------------------------------------------------------------
//销毁哈希对象
CryptDestroyHash(hHash);
hHash = 0;
}
//--------------------------------------------------------------------
//到此为止已经产生了用于解密的会话密钥。
//可能是从密钥块中获取的,也可能是从口令中获取。
//判断一次解密的字节数,它必须是ENCRYPT_BLOCK_SIZE的倍数。
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
dwBufferLen = dwBlockLen;
//分配内存
if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
{
HandleError("Out of memory!\n");
}
//解密文件,并写明文文件
do {
//--------------------------------------------------------------------
dwCount = fread(
pbBuffer,
1,
dwBlockLen,
hSource);
if(ferror(hSource))
{
HandleError("Error reading ciphertext!");
}
if(!CryptDecrypt(
hKey,
0,
feof(hSource),
0,
pbBuffer,
&dwCount))
{
HandleError("Error during CryptDecrypt!");
}
//写明文文件
fwrite(
pbBuffer,
1,
dwCount,
hDestination);
if(ferror(hDestination))
{
HandleError("Error writing plaintext!");
}
}
while(!feof(hSource));
status = TRUE;
//关闭文件
if(hSource)
fclose(hSource);
if(hDestination)
fclose(hDestination);
//--------------------------------------------------------------------
//释放内存
if(pbKeyBlob)
free(pbKeyBlob);
if(pbBuffer)
free(pbBuffer);
//销毁会话密钥
if(hKey)
CryptDestroyKey(hKey);
//销毁哈希对象
if(hHash)
CryptDestroyHash(hHash);
//释放CSP句柄
if(hCryptProv)
CryptReleaseContext(hCryptProv, 0);
return status;
}
}
//错误处理函数
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 + -