?? 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 + -