对称加解密的例子

前言

msdn中有个CSP对称加解密的例子, 验证整理了一下.

加密例子

// hw.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include <WinCrypt.h>
#pragma comment(lib, "crypt32.lib")

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the following #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define KEYLENGTH  0x00800000
void HandleError(char* s);

//--------------------------------------------------------------------
//  These additional #define statements are required.
#define ENCRYPT_ALGORITHM CALG_RC4
#define ENCRYPT_BLOCK_SIZE 8

//   Declare the function EncryptFile. The function definition
//   follows main.

BOOL EncryptFile(
    PCHAR szSource,
    PCHAR szDestination,
    PCHAR szPassword);

//--------------------------------------------------------------------
//   Begin main.

void main(void)
{
    PCHAR szSource = NULL;
    PCHAR szDestination = NULL;
    PCHAR szPassword = NULL;
    char  response = NULL;

    if (!(szSource = (char*)malloc(100))) {
        HandleError("Memory allocation failed.");
    }

    if (!(szDestination = (char*)malloc(100))) {
        HandleError("Memory allocation failed.");
    }

    if (!(szPassword = (char*)malloc(100))) {
        HandleError("Memory allocation failed.");
    }

//     printf("Encrypt a file. \n\n");
//     printf("Enter the name of the file to be encrypted: ");
//     scanf("%s", szSource);
    strcpy(szSource, "D:\\test\\src.txt");

//     printf("Enter the name of the output file: ");
//     scanf("%s", szDestination);
    strcpy(szDestination, "D:\\test\\dst.enc");

//     printf("Use a password to encrypt this file? ( y/n ) ");
//     getchar();
//     scanf("%c", &response);

    response = 'n';
    if (response == 'y') {
//         printf("Enter the password:");
//         scanf("%s", szPassword);
        strcpy(szPassword, "pwd");
    } else {
        printf("The key will be generated without using a password. \n");
        free(szPassword);
        szPassword = NULL;
    }

    //--------------------------------------------------------------------
    // Call EncryptFile to do the actual encryption.

    if (EncryptFile(szSource, szDestination, szPassword)) {
        printf("Encryption of the file %s was a success. \n", szSource);
        printf("The encrypted data is in file %s.\n", szDestination);
    } else {
        HandleError("Error encrypting file!");
    }
} // End of main

//--------------------------------------------------------------------
//   Code for the function EncryptFile called by main.

static BOOL EncryptFile(
    PCHAR szSource,
    PCHAR szDestination,
    PCHAR szPassword)
//--------------------------------------------------------------------
//   Parameters passed are:
//     szSource, the name of the input, a plaintext file.
//     szDestination, the name of the output, an encrypted file to be
//         created.
//     szPassword, either NULL if a password is not to be used or the
//          string that is the password.
{
    //--------------------------------------------------------------------
    //   Declare and initialize local variables.
    FILE* hSource;
    FILE* hDestination;
    HCRYPTPROV hCryptProv;
    HCRYPTKEY hKey;
    HCRYPTKEY hXchgKey;
    HCRYPTHASH hHash;
    PBYTE pbKeyBlob;
    DWORD dwKeyBlobLen;
    PBYTE pbBuffer;
    DWORD dwBlockLen;
    DWORD dwBufferLen;
    DWORD dwCount;

    //--------------------------------------------------------------------
    // Open source file.

    if (hSource = fopen(szSource, "rb")) {
        printf("The source plaintext file, %s, is open. \n", szSource);
    } else {
        HandleError("Error opening source plaintext file!");
    }

    //--------------------------------------------------------------------
    // Open destination file.

    if (hDestination = fopen(szDestination, "wb")) {
        printf("Destination file %s is open. \n", szDestination);
    } else {
        HandleError("Error opening destination ciphertext file!");
    }

    // Get handle to the default provider.
    if (CryptAcquireContext(
            &hCryptProv,
            NULL,
            MS_ENHANCED_PROV,
            PROV_RSA_FULL,
            0)) {
        printf("A cryptographic provider has been acquired. \n");
    } else {
        HandleError("Error during CryptAcquireContext!");
    }

    //--------------------------------------------------------------------
    //   Create the session key.

    if (!szPassword) {
        // @todo
        // 如果要使用指定的公钥, 调用CryptImportPublicKeyInfo导入公钥
        // CryptGenKey就可以不用调用了

        //---------------------------------------------------------------
        // No password was passed.
        // Encrypt the file with a random session key and write the key
        // to a file.

        //---------------------------------------------------------------
        // Create a random session key.
        if (CryptGenKey(
                hCryptProv,
                ENCRYPT_ALGORITHM,
                KEYLENGTH | CRYPT_EXPORTABLE,
                &hKey)) {
            printf("A session key has been created. \n");
        } else {
            HandleError("Error during CryptGenKey. \n");
        }

        //---------------------------------------------------------------
        // Get handle to the encrypter's exchange public key.

        if (CryptGetUserKey(
                hCryptProv,
                AT_KEYEXCHANGE,
                &hXchgKey)) {
            printf("The user public key has been retrieved. \n");
        } else {
            HandleError("User public key is not available \
                and may not exist.");
        }

        //---------------------------------------------------------------
        // Determine size of the key BLOB, and allocate memory.

        if (CryptExportKey(
                hKey,
                hXchgKey,
                SIMPLEBLOB,
                0,
                NULL,
                &dwKeyBlobLen)) {
            printf("The key BLOB is %d bytes long. \n", dwKeyBlobLen);
        } else {
            HandleError("Error computing BLOB length! \n");
        }

        if (pbKeyBlob = (BYTE*)malloc(dwKeyBlobLen)) {
            printf("Memory is allocated for the key BLOB. \n");
        } else {
            HandleError("Out of memory. \n");
        }

        //---------------------------------------------------------------
        // Encrypt and export session key into a simple key BLOB.

        if (CryptExportKey(
                hKey,
                hXchgKey,
                SIMPLEBLOB,
                0,
                pbKeyBlob,
                &dwKeyBlobLen)) {
            printf("The key has been exported. \n");
        } else {
            HandleError("Error during CryptExportKey!\n");
        }

        //---------------------------------------------------------------
        // Release key exchange key handle.
        CryptDestroyKey(hXchgKey);
        hXchgKey = 0;
        //---------------------------------------------------------------
        // Write size of key BLOB to destination file.
        fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination);

        if (ferror(hDestination)) {
            HandleError("Error writing header.");
        } else {
            printf("A file header has been written. \n");
        }

        //--------------------------------------------------------------
        // Write key BLOB to destination file.
        fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination);

        if (ferror(hDestination)) {
            HandleError("Error writing header");
        } else {
            printf("The key BLOB has been written to the file. \n");
        }
    } else {
        //--------------------------------------------------------------------
        // The file will be encrypted with a session key derived from a
        // password.
        // The session key will be recreated when the file is decrypted
        // only if the password used to create the key is available.

        //--------------------------------------------------------------------
        // Create a hash object.
        if (CryptCreateHash(
                hCryptProv,
                CALG_MD5,
                0,
                0,
                &hHash)) {
            printf("A hash object has been created. \n");
        } else {
            HandleError("Error during CryptCreateHash!\n");
        }

        //--------------------------------------------------------------------
        // Hash the password.

        if (CryptHashData(
                hHash,
                (BYTE*)szPassword,
                strlen(szPassword),
                0)) {
            printf("The password has been added to the hash. \n");
        } else {
            HandleError("Error during CryptHashData. \n");
        }

        //--------------------------------------------------------------------
        // Derive a session key from the hash object.

        if (CryptDeriveKey(
                hCryptProv,
                ENCRYPT_ALGORITHM,
                hHash,
                KEYLENGTH,
                &hKey)) {
            printf("An encryption key is derived from the password hash. \n");
        } else {
            HandleError("Error during CryptDeriveKey!\n");
        }

        //--------------------------------------------------------------------
        // Destroy the hash object.
        CryptDestroyHash(hHash);
        hHash = 0;
    }

    //--------------------------------------------------------------------
    //  The session key is now ready. If it is not a key derived from a
    //  password, the session key encrypted with the encrypter's private
    //  key has been written to the destination file.
    //--------------------------------------------------------------------
    // Determine number of bytes to encrypt at a time.
    // This must be a multiple of ENCRYPT_BLOCK_SIZE.
    // ENCRYPT_BLOCK_SIZE is set by a #define statement.
    dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;

    //--------------------------------------------------------------------
    // Determine the block size. If a block cipher is used,
    // it must have room for an extra block.

    if (ENCRYPT_BLOCK_SIZE > 1) {
        dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
    } else {
        dwBufferLen = dwBlockLen;
    }

    //--------------------------------------------------------------------
    // Allocate memory.
    if (pbBuffer = (BYTE*)malloc(dwBufferLen)) {
        printf("Memory has been allocated for the buffer. \n");
    } else {
        HandleError("Out of memory. \n");
    }

    //--------------------------------------------------------------------
    // In a do loop, encrypt the source file and write to the source file.

    do {
        //--------------------------------------------------------------------
        // Read up to dwBlockLen bytes from the source file.
        dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);

        if (ferror(hSource)) {
            HandleError("Error reading plaintext!\n");
        }

        //--------------------------------------------------------------------
        // Encrypt data.
        if (!CryptEncrypt(
                hKey,
                0,
                feof(hSource),
                0,
                pbBuffer,
                &dwCount,
                dwBufferLen)) {
            HandleError("Error during CryptEncrypt. \n");
        }

        //--------------------------------------------------------------------
        // Write data to the destination file.
        fwrite(pbBuffer, 1, dwCount, hDestination);

        if (ferror(hDestination)) {
            HandleError("Error writing ciphertext.");
        }
    } while (!feof(hSource));

    //--------------------------------------------------------------------
    //  End the do loop when the last block of the source file has been
    //  read, encrypted, and written to the destination file.

    //--------------------------------------------------------------------
    // Close files.

    if (hSource) {
        fclose(hSource);
    }

    if (hDestination) {
        fclose(hDestination);
    }

    //--------------------------------------------------------------------
    // Free memory.

    if (pbBuffer) {
        free(pbBuffer);
    }

    //--------------------------------------------------------------------
    // Destroy session key.

    if (hKey) {
        CryptDestroyKey(hKey);
    }

    //--------------------------------------------------------------------
    // Release key exchange key handle.

    if (hXchgKey) {
        CryptDestroyKey(hXchgKey);
    }

    //--------------------------------------------------------------------
    // Destroy hash object.

    if (hHash) {
        CryptDestroyHash(hHash);
    }

    //--------------------------------------------------------------------
    // Release provider handle.

    if (hCryptProv) {
        CryptReleaseContext(hCryptProv, 0);
    }

    return(TRUE);
} // End of Encryptfile

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char* s)
{
    fprintf(stderr, "An error occurred in running the program. \n");
    fprintf(stderr, "%s\n", s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError

解密例子

// hw.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include <WinCrypt.h>
#pragma comment(lib, "crypt32.lib")

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the following #define and #include statements listed
//   under #includes and #defines.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define KEYLENGTH  0x00800000
void HandleError(char* s);

//--------------------------------------------------------------------
//   The following #define statements are also required.

#define ENCRYPT_ALGORITHM CALG_RC4
#define ENCRYPT_BLOCK_SIZE 8

//--------------------------------------------------------------------
//    Declare the function DecryptFile. Code for the function follows
//    main.

BOOL DecryptFile(
    PCHAR szSource,
    PCHAR szDestination,
    PCHAR szPassword);

void main(void)
{
    //--------------------------------------------------------------------
    //    Declare and initialize variables.
    PCHAR szSource;
    PCHAR szDestination;
    PCHAR szPassword;
    char  response;

    if (!(szSource = (char*)malloc(100))) {
        HandleError("Memory allocation failed.");
    }

    if (!(szDestination = (char*)malloc(100))) {
        HandleError("Memory allocation failed.");
    }

    if (!(szPassword = (char*)malloc(100))) {
        HandleError("Memory allocation failed.");
    }

//     printf("Decrypt a file. \n\n");
//     printf("Enter the name of the file to be decrypted: ");
//     scanf("%s", szSource);
    strcpy(szSource, "d:\\test\\dst.enc");

//     printf("Enter the name of the output file: ");
//     scanf("%s", szDestination);

    strcpy(szDestination, "d:\\test\\dst_dec.txt");

//     printf("Was a password used to encrypt this file? ( y/n ) ");
//     getchar();
//     scanf("%c", &response);

    response = 'n';
    if (response == 'y') {
        printf("Enter the password:");
        scanf("%s", szPassword);
    } else {
        printf("The key will be generated without using a password. \n");
        free(szPassword);
        szPassword = NULL;
    }

    if (!DecryptFile(szSource, szDestination, szPassword)) {
        printf("\nError decrypting file. \n");
    } else {
        printf("\nDecryption of file %s succeeded. \n", szSource);
        printf("The decrypted file is %s .\n", szDestination);
    }
} // End of main

//--------------------------------------------------------------------
//    Define the function Decryptfile.

static BOOL DecryptFile(
    PCHAR szSource,
    PCHAR szDestination,
    PCHAR szPassword)
{
    //--------------------------------------------------------------------
    //   Declare and initialize local variables.
    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;

    //--------------------------------------------------------------------
    // Open source file.
    if (!(hSource = fopen(szSource, "rb"))) {
        HandleError("Error opening ciphertext file!");
    }

    //--------------------------------------------------------------------
    // Open destination file.

    if (!(hDestination = fopen(szDestination, "wb"))) {
        HandleError("Error opening plaintext file!");
    }

    //--------------------------------------------------------------------
    // Get a handle to the default provider.
    if (!CryptAcquireContext(
            &hCryptProv,
            NULL,
            MS_ENHANCED_PROV,
            PROV_RSA_FULL,
            0)) {
        HandleError("Error during CryptAcquireContext!");
    }

    //--------------------------------------------------------------------
    //  Check for existence of a password.

    if (!szPassword) {
        //--------------------------------------------------------------------
        // Decrypt the file with the saved session key.
        // Read key BLOB length from source file, and allocate memory.
        fread(&dwKeyBlobLen, sizeof(DWORD), 1, hSource);

        if (ferror(hSource) || feof(hSource)) {
            HandleError("Error reading file header!");
        }

        if (!(pbKeyBlob = (BYTE*)malloc(dwKeyBlobLen))) {
            HandleError("Memory allocation error.");
        }

        //--------------------------------------------------------------------
        // Read key BLOB from source file.
        fread(pbKeyBlob, 1, dwKeyBlobLen, hSource);

        if (ferror(hSource) || feof(hSource)) {
            HandleError("Error reading file header!\n");
        }

        //--------------------------------------------------------------------
        // Import key BLOB into CSP.
        if (!CryptImportKey(
                hCryptProv,
                pbKeyBlob,
                dwKeyBlobLen,
                0,
                0,
                &hKey)) {
            HandleError("Error during CryptImportKey!");
        }
    } else {
        //--------------------------------------------------------------------
        // Decrypt the file with a session key derived from a password.

        //--------------------------------------------------------------------
        // Create a hash object.
        if (!CryptCreateHash(
                hCryptProv,
                CALG_MD5,
                0,
                0,
                &hHash)) {
            HandleError("Error during CryptCreateHash!");
        }

        //--------------------------------------------------------------------
        // Hash in the password data.

        if (!CryptHashData(
                hHash,
                (BYTE*)szPassword,
                strlen(szPassword),
                0)) {
            HandleError("Error during CryptHashData!");
        }

        //--------------------------------------------------------------------
        // Derive a session key from the hash object.

        if (!CryptDeriveKey(
                hCryptProv,
                ENCRYPT_ALGORITHM,
                hHash,
                KEYLENGTH,
                &hKey)) {
            HandleError("Error during CryptDeriveKey!");
        }

        //--------------------------------------------------------------------
        // Destroy the hash object.
        CryptDestroyHash(hHash);
        hHash = 0;
    }

    //--------------------------------------------------------------------
    //   The decryption key is now available, either having been imported
    //   from a BLOB read in from the source file or having been created
    //   using the password. This point in the program is not reached if
    //   the decryption key is not available.
    //--------------------------------------------------------------------
    // Determine the number of bytes to decrypt at a time.
    // This must be a multiple of ENCRYPT_BLOCK_SIZE.
    dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
    dwBufferLen = dwBlockLen;

    //--------------------------------------------------------------------
    // Allocate memory.

    if (!(pbBuffer = (BYTE*)malloc(dwBufferLen))) {
        HandleError("Out of memory!\n");
    }

    //--------------------------------------------------------------------
    // Decrypt source file, and write to destination file.

    do {
        //--------------------------------------------------------------------
        // Read up to dwBlockLen bytes from source file.
        dwCount = fread(
                      pbBuffer,
                      1,
                      dwBlockLen,
                      hSource);

        if (ferror(hSource)) {
            HandleError("Error reading ciphertext!");
        }

        //--------------------------------------------------------------------
        // Decrypt data.
        if (!CryptDecrypt(
                hKey,
                0,
                feof(hSource),
                0,
                pbBuffer,
                &dwCount)) {
            HandleError("Error during CryptDecrypt!");
        }

        //--------------------------------------------------------------------
        // Write data to destination file.
        fwrite(
            pbBuffer,
            1,
            dwCount,
            hDestination);

        if (ferror(hDestination)) {
            HandleError("Error writing plaintext!");
        }
    } while (!feof(hSource));

    status = TRUE;

    //--------------------------------------------------------------------
    // Close files.
    if (hSource) {
        fclose(hSource);
    }

    if (hDestination) {
        fclose(hDestination);
    }

    //--------------------------------------------------------------------
    // Free memory.

    if (pbKeyBlob) {
        free(pbKeyBlob);
    }

    if (pbBuffer) {
        free(pbBuffer);
    }

    //--------------------------------------------------------------------
    // Destroy session key.

    if (hKey) {
        CryptDestroyKey(hKey);
    }

    //--------------------------------------------------------------------
    // Destroy hash object.
    if (hHash) {
        CryptDestroyHash(hHash);
    }

    //--------------------------------------------------------------------
    // Release provider handle.

    if (hCryptProv) {
        CryptReleaseContext(hCryptProv, 0);
    }

    return status;
} // End of Decryptfile

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char* s)
{
    fprintf(stderr, "An error occurred in running the program. \n");
    fprintf(stderr, "%s\n", s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值