对称加解密的例子

来源:互联网 发布:python socket 异步 编辑:程序博客网 时间:2024/04/27 13:26

前言

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  0x00800000void 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  0x00800000void 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
0 0