文件解密CryptDecrypt和导入密钥CryptImportKey学习笔记

上一篇使用了加密和导出密钥,这一篇讲解一下文件解密和导出密钥

#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <conio.h>

#pragma comment (lib, "advapi32")

#define KEYLENGTH  0x00800000
#define ENCRYPT_ALGORITHM CALG_RC4 
#define ENCRYPT_BLOCK_SIZE 8 

bool MyDecryptFile(
    LPTSTR szSource,
    LPTSTR szDestination,
    LPTSTR szPassword,
    LPTSTR szkeyblob);

void MyHandleError(
    LPTSTR psz,
    int nErrorNumber);

int main()
{

    LPTSTR pszSource = (LPTSTR)L"D:\\testSecurity\\hello22.txt";
    LPTSTR pszDestination = (LPTSTR)L"D:\\testSecurity\\hello33.txt";
    LPTSTR pszkeyblobSource = (LPTSTR)L"D:\\testSecurity\\exportkeyblob.txt";
    LPTSTR pszPassword = NULL;
    //LPTSTR pszPassword = NULL;
    //pszPassword = (LPTSTR)L"123456";


    //---------------------------------------------------------------
    // Call EncryptFile to do the actual encryption.
    if (MyDecryptFile(pszSource, pszDestination, pszPassword, pszkeyblobSource))
    {
        _tprintf(TEXT("Encryption of the file %s was successful. \n"),pszSource);
        _tprintf(TEXT("The encrypted data is in file %s.\n"),pszDestination);
    }
    else
    {
        MyHandleError(TEXT("Error encrypting file!\n"),GetLastError());
    }
    getchar();
    return 0;
}
bool MyDecryptFile(LPTSTR pszSourceFile,LPTSTR pszDestinationFile,LPTSTR pszPassword,LPTSTR pszkeyblobSource)
{
    //---------------------------------------------------------------
    // Declare and initialize local variables.
    bool fReturn = false;
    HANDLE hSourceFile = INVALID_HANDLE_VALUE;
    HANDLE hDestinationFile = INVALID_HANDLE_VALUE;
    HANDLE hkeyblobsoucerFile = INVALID_HANDLE_VALUE;
    HCRYPTKEY hKey = NULL;
    HCRYPTHASH hHash = NULL;

    HCRYPTPROV hCryptProv = NULL;

    DWORD dwCount;
    PBYTE pbBuffer = NULL;
    DWORD dwBlockLen;
    DWORD dwBufferLen;

    //---------------------------------------------------------------
    // Open the source file. 
    hSourceFile = CreateFile(
        pszSourceFile,
        FILE_READ_DATA,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (INVALID_HANDLE_VALUE != hSourceFile)
    {
        _tprintf(TEXT("The source encrypted file, %s, is open. \n"),pszSourceFile);
    }
    else
    {
        _tprintf(TEXT("The source encrypted file, %s, is open. \n"),pszSourceFile);
        MyHandleError(TEXT("Error opening source plaintext file!\n"),GetLastError());
        goto Exit_MyDecryptFile;
    }

    //---------------------------------------------------------------
    // Open the destination file. 
    hDestinationFile = CreateFile(
        pszDestinationFile,
        FILE_WRITE_DATA,
        FILE_SHARE_READ,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (INVALID_HANDLE_VALUE != hDestinationFile)
    {
        _tprintf(TEXT("The destination file, %s, is open. \n"),pszDestinationFile);
    }
    else
    {
        MyHandleError(TEXT("Error opening destination file!\n"),GetLastError());
        goto Exit_MyDecryptFile;
    }

    //---------------------------------------------------------------
    // Get the handle to the default provider. 
    if (!CryptAcquireContext(
        &hCryptProv,
        NULL,
        MS_ENHANCED_PROV,
        PROV_RSA_FULL, //这里为使用的加密策略
        0))
    {
        //
        if (GetLastError() == NTE_BAD_KEYSET)
        {
            if (!CryptAcquireContext(
                &hCryptProv,
                NULL,
                MS_ENHANCED_PROV,
                PROV_RSA_FULL,
                CRYPT_NEWKEYSET))
            {
                MyHandleError(TEXT("Error during CryptAcquireContext!\n"),GetLastError());
                goto Exit_MyDecryptFile;
                //return FALSE;
            }
        }
        else
        {
            MyHandleError(TEXT("Error during CryptAcquireContext!\n"),GetLastError());
            goto Exit_MyDecryptFile;
            //return FALSE;
        }
    }
    _tprintf(TEXT("A cryptographic provider has been acquired. \n"));
    // Create the session key.
    if (pszPassword == NULL)
    {
        //-----------------------------------------------------------
        // Decrypt the file with the saved session key. 
        DWORD dwKeyBlobLen = 0x00;
        PBYTE pbKeyBlob = NULL;
        hkeyblobsoucerFile = CreateFile(
            pszkeyblobSource,
            FILE_READ_DATA,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);
        if (INVALID_HANDLE_VALUE != hkeyblobsoucerFile)
        {
            _tprintf(TEXT("The source encrypted file, %s, is open. \n"), pszDestinationFile);
        }
        else
        {
            _tprintf(TEXT("The source encrypted file, %s, is open. \n"), pszDestinationFile);
            MyHandleError(TEXT("Error opening source plaintext file!\n"), GetLastError());
            goto Exit_MyDecryptFile;
        }

        //先读取keyBlob的长度,key blob文件的前4字节
        if (!ReadFile(
            hkeyblobsoucerFile,
            &dwKeyBlobLen,
            sizeof(DWORD),
            &dwCount,
            NULL))
        {
            MyHandleError(TEXT("Error reading key BLOB length!\n"),GetLastError());
            goto Exit_MyDecryptFile;
        }
        // 为keyblob分配内存,读出的长度要拿第一个字节
        dwKeyBlobLen = dwKeyBlobLen & 0x000000FF;
        if (!(pbKeyBlob = (PBYTE)malloc(dwKeyBlobLen)))
        {
            MyHandleError(TEXT("Memory allocation error.\n"),E_OUTOFMEMORY);
        }
        if (!ReadFile(
            hkeyblobsoucerFile,
            pbKeyBlob,
            dwKeyBlobLen,
            &dwCount,
            NULL))
        {
            MyHandleError(TEXT("Error reading key BLOB length!\n"),GetLastError());
            goto Exit_MyDecryptFile;
        }

        //将key blob导入CSP容器
        if (!CryptImportKey(
            hCryptProv,
            pbKeyBlob,
            dwKeyBlobLen,
            0,
            0,
            &hKey))
        {
            MyHandleError(TEXT("Error during CryptImportKey!/n"),GetLastError());
            goto Exit_MyDecryptFile;
        }
        if (pbKeyBlob)
        {
            free(pbKeyBlob);
        }
    }
    else
    {
        // 创建一个hash对象,将password hash以后再通过CryptDeriveKey得到密钥
        if (!CryptCreateHash(
            hCryptProv,
            CALG_MD5,
            0,
            0,
            &hHash))
        {
            MyHandleError(TEXT("Error during CryptCreateHash!\n"),GetLastError());
            goto Exit_MyDecryptFile;
        }

        // Hash password后将hash信息保存在hHash中 
        if (!CryptHashData(
            hHash,
            (BYTE *)pszPassword,
            lstrlen(pszPassword),
            0))
        {
            MyHandleError(TEXT("Error during CryptHashData!\n"),GetLastError());
            goto Exit_MyDecryptFile;
        }

        // 再使用已经对password的hash对象生成密钥 
        if (!CryptDeriveKey(
            hCryptProv,
            ENCRYPT_ALGORITHM,
            hHash,
            KEYLENGTH,
            &hKey))
        {
            MyHandleError(TEXT("Error during CryptDeriveKey!\n"),GetLastError());
            goto Exit_MyDecryptFile;
        }
    }
    //每一次加密的字节长度,必须要是ENCRYPT_BLOCK_SIZE的整数倍
    dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
    dwBufferLen = dwBlockLen;

    // Allocate memory for the file read buffer. 
    if (!(pbBuffer = (PBYTE)malloc(dwBufferLen)))
    {
        MyHandleError(TEXT("Out of memory!\n"), E_OUTOFMEMORY);
        goto Exit_MyDecryptFile;
    }
    //解密数据 
    bool fEOF = false;
    do
    {
        //从要加密的文件每次读取dwBlockLen个字节进行加密
        if (!ReadFile(
            hSourceFile,
            pbBuffer,
            dwBlockLen,
            &dwCount,
            NULL))
        {
            MyHandleError(TEXT("Error reading from source file!\n"),GetLastError());
            goto Exit_MyDecryptFile;
        }

        if (dwCount <= dwBlockLen)
        {
            fEOF = TRUE;
        }
        //解密数据
        if (!CryptDecrypt(
            hKey,
            0,
            fEOF,
            0,
            pbBuffer,
            &dwCount))
        {
            MyHandleError(TEXT("Error during CryptDecrypt!\n"),GetLastError());
            goto Exit_MyDecryptFile;
        }

        // 将解密后的数据写入目标文件. 
        if (!WriteFile(
            hDestinationFile,
            pbBuffer,
            dwCount,
            &dwCount,
            NULL))
        {
            MyHandleError(TEXT("Error writing ciphertext.\n"),GetLastError());
            goto Exit_MyDecryptFile;
        }

    } while (!fEOF);

    fReturn = true;

Exit_MyDecryptFile:

    //---------------------------------------------------------------
    // Free the file read buffer.
    if (pbBuffer)
    {
        free(pbBuffer);
    }

    //---------------------------------------------------------------
    // Close files.
    if (hSourceFile)
    {
        CloseHandle(hSourceFile);
    }

    if (hDestinationFile)
    {
        CloseHandle(hDestinationFile);
    }

    //-----------------------------------------------------------
    // Release the hash object. 
    if (hHash)
    {
        if (!(CryptDestroyHash(hHash)))
        {
            MyHandleError(TEXT("Error during CryptDestroyHash.\n"),GetLastError());
        }

        hHash = NULL;
    }

    //---------------------------------------------------------------
    // Release the session key. 
    if (hKey)
    {
        if (!(CryptDestroyKey(hKey)))
        {
            MyHandleError(TEXT("Error during CryptDestroyKey!\n"),GetLastError());
        }
    }

    //---------------------------------------------------------------
    // Release the provider handle. 
    if (hCryptProv)
    {
        if (!(CryptReleaseContext(hCryptProv, 0)))
        {
            MyHandleError(TEXT("Error during CryptReleaseContext!\n"),GetLastError());
        }
    }
    getchar();
    return fReturn;
}

void MyHandleError(LPTSTR psz, int nErrorNumber)
{
    _ftprintf(stderr, TEXT("An error occurred in the program. \n"));
    _ftprintf(stderr, TEXT("%s\n"), psz);
    _ftprintf(stderr, TEXT("Error number %x.\n"), nErrorNumber);
}

已经加密的文件:
这里写图片描述
导入密钥文件:
这里写图片描述
解密后的文件:
这里写图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值