使用rsa和Windows crypto API加密/解密字符串和文件

时间:2019-02-02 12:26:22

标签: c++ file encryption rsa

我正在开发一个用于安全文件加密和数据交换的程序。

由于我不是加密专家,所以我陷入了困境……也许有人可以帮助我完成和纠正某些功能。

我认为我的cryptoFileWithPublicKey函数可以工作,但是我无法测试它,因为cryptoFileWithPrivateKey函数不能。对于cryptoStringWithPublicKey函数,它也打印出一些垃圾,在我看来它确实起作用。但是我又无法测试它,因为我不知道如何正确编写解密函数。

我的主要功能中包含以下代码:

LPCWSTR szPemPrivateKey = 
    L"-----BEGIN CERTIFICATE-----"
    "MIIEowIBAAKCAQEAqRLhZXK29Xo5YdSoMdAeMHwDYAmThPSJzbQaBhVLCY1DTQr0"
    "JRkvd+0xfdwih97bWUXVpxuOgYH9hofIzZGPZSErmCkBbzs8Q344ECFraG/1zNmH"
    "M2QaMLewztbZtpt9whIgaxwCRuoJWSmFzlp2ny0PtOzHeWf9c+iqEAnYxqrocGED"
    "Rdf08/8siZLQDZugSjsmg9C0oLhGvpTruh0S4Gg9IPjemDD6IWhOESbZC239f1++"
    "hsBLRIADWzRFt4Ka4p+VcWpJXSjkifUYLsvu9MceJgUDvGbViB1sFOhCc6C3B3e5"
    "y2WPfi+p56T+lPWy8BjmYqpWBlYWp8YTruUdxQIDAQABAoIBAEukl9U0iqivI0ci"
    "xpFqxGb6xOPNxQNiCNlQb6gzFJxUaDzq3qpOZ09nfpIJ0CUrzsVVGi6mhI5qowvy"
    "aiOWsSoUuhVcmzixrtefe+OzoANcvAMHe5bBfXo4ZNFVjJhHXu9Z/skNAfPKN559"
    "llDpZlL27SUMHn6xyNJ30MZWMXdIOkBa6FCuu35ygpUt9gKQ6vZ6xUNvODnoTjVs"
    "A/+d3G+3NMkZwkFy2ygJtpfrPhhby4AxUtW4/Ms6FImB7R0XvNJ4+x43PCFE61N/"
    "c77BXyIE7DRfoh6+sbaQnzZIvYEucTXdroZUlfNaDryGRClue8c9Mc9KCfje0Pk9"
    "0SRrCiECgYEA6eETNhjIKN1q3De99UujMLpy46JxyulDvQj8wsvYmozAubngL4fQ"
    "1DcOSsUzpM7u0FHQW0mDeZXn3/qXIT2bQHquIgo3DiOHXeE4iiKwQbtFl2t4klwo"
    "l4lpUBvZrqGxXRyicOsOwZ4dWUUxnsaCShtjMzxdSxs8hs282E7c1RkCgYEAuRCr"
    "Pi8oHr4S4JM0Os1dbkQYlpLJvTANFX6ACpXOiC+Uyi6Klanxc7ENM4VZQoqEd/nf"
    "3EsYWqjwD5RHjm0P0mKDpTGorU7WhsBj/qp6SUB9f9ZgI0QACfcI7HFD1oiskJi1"
    "+NtsLw9ZeunX9Ru0jtbQbL9vLajZ7qJjCPpil40CgYEAqsG7Dg8v7K4kfB5yoaqU"
    "vloS0eJjpJuE6nqqWOsN/WDwwWlVpj5KGPcNh0fNufGf6RciwdO9m0L4pc5HE2zw"
    "cjZf9thwc/E6vy9V4X0MJSG+4JwFzw5cUK9x5Zw/5cGGRo5Gh50HDBQOJ4Regyc6"
    "LzMpzVmwX8rF+UIzM9b4YtkCgYBzgMLP+dCZd1oCzf0QIjKI6nlKKO0+ZaoU2zIA"
    "6UTQ3JmJooieJkXrRfqOSFDQZfGNi+e67yeRFdVWc95BNzJjxVaSmK7FE+pyicsf"
    "G7lc1KI/UkYIXJ2Fmqf4Ii0LzZueV6FjY1de+76GJ0LA2PzVFZ9Z8BTss3DpLnKP"
    "HO7B1QKBgCqY+fzJO5JlZgQ7++70VjPVMH8sbpAYMUhadLb27IYdnfCMfMc0aos8"
    "9W3cUPJEJ6+HExKiBs+bjIIppPz+jlb20K445O6SwPRkg38yFEd0EjRc+PkxZXM4"
    "2i0rEOzV/2RqvJdMJkWW2SSz1TBuvW5sVgKPtyx6lCi1QWQ+h3Gj"
    "-----END CERTIFICATE-----";


LPCWSTR szPemPublicKey =
    L"-----BEGIN CERTIFICATE-----"
    "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqRLhZXK29Xo5YdSoMdAe"
    "MHwDYAmThPSJzbQaBhVLCY1DTQr0JRkvd+0xfdwih97bWUXVpxuOgYH9hofIzZGP"
    "ZSErmCkBbzs8Q344ECFraG/1zNmHM2QaMLewztbZtpt9whIgaxwCRuoJWSmFzlp2"
    "ny0PtOzHeWf9c+iqEAnYxqrocGEDRdf08/8siZLQDZugSjsmg9C0oLhGvpTruh0S"
    "4Gg9IPjemDD6IWhOESbZC239f1++hsBLRIADWzRFt4Ka4p+VcWpJXSjkifUYLsvu"
    "9MceJgUDvGbViB1sFOhCc6C3B3e5y2WPfi+p56T+lPWy8BjmYqpWBlYWp8YTruUd"
    "xQIDAQAB"
    "-----END CERTIFICATE-----";


int main()
{
    RSA rsa = RSA();

    _TCHAR infile[] = L"c:\\test.txt";
    _TCHAR outfile[] = L"c:\\test.enc";
    _TCHAR decfile[] = L"c:\\test.dec.txt";

    rsa.EncryptFileWithPublicKey(szPemPublicKey, infile, outfile);
    rsa.DecryptFileWithPrivateKey(szPemPrivateKey, outfile, decfile);

    BYTE ciphertext = NULL;
    BYTE cleartext[] = "test";

    rsa.EncryptStringWithPublicKey(szPemPublicKey, cleartext, &ciphertext);
    printf("CIPHER: %s\n", ciphertext);
}

还有RSA类:

#include "pch.h"
#include "RSA.h"


RSA::RSA()
{
}


RSA::~RSA()
{
}

// Keys
/*
int Keys(_TCHAR* strPublicKeyFile, _TCHAR* strPrivateKeyFile)
{
    // Variables
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hKey = NULL;
    DWORD dwPublicKeyLen = 0;
    DWORD dwPrivateKeyLen = 0;
    BYTE* pbPublicKey = NULL;
    BYTE* pbPrivateKey = NULL;
    HANDLE hPublicKeyFile = NULL;
    HANDLE hPrivateKeyFile = NULL;
    DWORD lpNumberOfBytesWritten = 0;

    __try
    {
        // Acquire access to key container
        _tprintf(_T("CryptAcquireContext...\n"));
        if (!CryptAcquireContext(&hCryptProv, _T("AlejaCMa.EncryptDecrypt"), NULL, PROV_RSA_FULL, 0))
        {
            // Error
            _tprintf(_T("CryptAcquireContext error 0x%x\n"), GetLastError());

            // Try to create a new key container
            if (!CryptAcquireContext(&hCryptProv, _T("AlejaCMa.EncryptDecrypt"), NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
            {
                // Error
                _tprintf(_T("CryptAcquireContext error 0x%x\n"), GetLastError());
                return 1;
            }
        }

        // Generate new key pair
        _tprintf(_T("CryptGenKey...\n"));
        if (!CryptGenKey(hCryptProv, AT_KEYEXCHANGE, CRYPT_ARCHIVABLE, &hKey))
        {
            // Error
            _tprintf(_T("CryptGenKey error 0x%x\n"), GetLastError());
            return 1;
        }

        // Get public key size
        _tprintf(_T("CryptExportKey...\n"));
        if (!CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyLen))
        {
            // Error
            _tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
            return 1;
        }

        // Create a buffer for the public key
        _tprintf(_T("malloc...\n"));
        if (!(pbPublicKey = (BYTE *)malloc(dwPublicKeyLen)))
        {
            // Error
            _tprintf(_T("malloc error 0x%x\n"), GetLastError());
            return 1;
        }

        // Get public key
        _tprintf(_T("CryptExportKey...\n"));
        if (!CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbPublicKey, &dwPublicKeyLen))
        {
            // Error
            _tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
            return 1;
        }

        // Get private key size
        _tprintf(_T("CryptExportKey...\n"));
        if (!CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyLen))
        {
            // Error
            _tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
            return 1;
        }

        // Create a buffer for the private key
        _tprintf(_T("malloc...\n"));
        if (!(pbPrivateKey = (BYTE *)malloc(dwPrivateKeyLen)))
        {
            // Error
            _tprintf(_T("malloc error 0x%x\n"), GetLastError());
            return 1;
        }


        // Get private key
        _tprintf(_T("CryptExportKey...\n"));
        if (!CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbPrivateKey, &dwPrivateKeyLen))
        {
            // Error
            _tprintf(_T("CryptExportKey error 0x%x\n"), GetLastError());
            return 1;
        }

        // Create a file to save the public key
        _tprintf(_T("CreateFile...\n"));
        if ((hPublicKeyFile = CreateFile(
            strPublicKeyFile,
            GENERIC_WRITE,
            0,
            NULL,
            CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        )) == INVALID_HANDLE_VALUE)
        {
            // Error
            _tprintf(_T("CreateFile error 0x%x\n"), GetLastError());
            return 1;
        }


        // Write the public key to the file
        _tprintf(_T("WriteFile...\n"));
        if (!WriteFile(
            hPublicKeyFile,
            (LPCVOID)pbPublicKey,
            dwPublicKeyLen,
            &lpNumberOfBytesWritten,
            NULL
        ))
        {
            // Error
            _tprintf(_T("WriteFile error 0x%x\n"), GetLastError());
            return 1;
        }

        // Create a file to save the private key
        _tprintf(_T("CreateFile...\n"));
        if ((hPrivateKeyFile = CreateFile(
            strPrivateKeyFile,
            GENERIC_WRITE,
            0,
            NULL,
            CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        )) == INVALID_HANDLE_VALUE)
        {
            // Error
            _tprintf(_T("CreateFile error 0x%x\n"), GetLastError());
            return 1;
        }

        // Write the private key to the file
        _tprintf(_T("WriteFile...\n"));
        if (!WriteFile(
            hPrivateKeyFile,
            (LPCVOID)pbPrivateKey,
            dwPrivateKeyLen,
            &lpNumberOfBytesWritten,
            NULL
        ))
        {
            // Error
            _tprintf(_T("WriteFile error 0x%x\n"), GetLastError());
            return 1;
        }
        return 0;
    }

    __finally
    {
        // Clean up
        if (!pbPublicKey) {
            _tprintf(_T("free...\n"));
            free(pbPublicKey);
        }

        if (!pbPrivateKey) {
            _tprintf(_T("free...\n"));
            free(pbPrivateKey);
        }

        if (hPublicKeyFile) {
            _tprintf(_T("CloseHandle...\n"));
            CloseHandle(hPublicKeyFile);
        }

        if (hPrivateKeyFile) {
            _tprintf(_T("CloseHandle...\n"));
            CloseHandle(hPrivateKeyFile);
        }

        if (hKey) {
            _tprintf(_T("CryptDestroyKey...\n"));
            CryptDestroyKey(hKey);
        }

        if (hCryptProv) {
            _tprintf(_T("CryptReleaseContext...\n"));
            CryptReleaseContext(hCryptProv, 0);
        }
    }
}
*/
// End of Keys

// Encrypt file
int RSA::EncryptFileWithPublicKey(LPCWSTR szPemPublicKey, _TCHAR* strPlainFile, _TCHAR* strEncryptedFile)
{
    // Variables
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hKey = NULL;
    DWORD dwPublicKeyLen = 0;
    DWORD dwDataLen = 0;
    DWORD dwEncryptedLen = 0;
    BYTE* pbPublicKey = NULL;
    BYTE* pbData = NULL;
    HANDLE hPublicKeyFile = NULL;
    HANDLE hEncryptedFile = NULL;
    HANDLE hPlainFile = NULL;
    DWORD lpNumberOfBytesWritten = 0;

    BYTE derPubKey[2048];
    DWORD derPubKeyLen = 2048;
    CERT_PUBLIC_KEY_INFO *publicKeyInfo = NULL;
    DWORD publicKeyInfoLen = 0;
    HANDLE hFile = NULL;

    __try
    {
        /*
        // Acquire access to key container
        _tprintf(_T("CryptAcquireContext...\n"));
        if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
        {
            // Error
            _tprintf(_T("CryptAcquireContext error 0x%x\n"), GetLastError());
            return 1;
        }
        */

        /*
         * Read the public key cert from the file
         */
        /*
        hFile = CreateFileA("c:\\pub.pem", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if(hFile == INVALID_HANDLE_VALUE)
        {
            fprintf(stderr, "Failed to open file. error: %d\n", GetLastError());
        }

        if(!ReadFile(hFile, pemPubKey, 2048, &readLen, NULL))
        {
            fprintf(stderr, "Failed to read file. error: %d\n", GetLastError());
        }
        */
        /*
         * Convert from PEM format to DER format - removes header and footer and decodes from base64
         */
        if(!CryptStringToBinary(szPemPublicKey, 0, CRYPT_STRING_BASE64HEADER, derPubKey, &derPubKeyLen, NULL, NULL))
        {
            //fprintf(stderr, "CryptStringToBinary failed. Err: %d\n", GetLastError());
            return -1;
        }

        /*
         * Decode from DER format to CERT_PUBLIC_KEY_INFO
         */
        if(!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, derPubKey, derPubKeyLen, CRYPT_ENCODE_ALLOC_FLAG, NULL, &publicKeyInfo, &publicKeyInfoLen))
        {
            //fprintf(stderr, "CryptDecodeObjectEx 1 failed. Err: %p\n", GetLastError());
            return -1;
        }

        /*
         * Acquire context
         */
        if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
        {
            {
                //printf("CryptAcquireContext failed - err=0x%x.\n", GetLastError());
                return -1;
            }
        }

        /*
         * Import the public key using the context
         */
        if(!CryptImportPublicKeyInfo(hCryptProv, X509_ASN_ENCODING, publicKeyInfo, &hKey))
        {
            //fprintf(stderr, "CryptImportPublicKeyInfo failed. error: %d\n", GetLastError());
            return -1;
        }
        LocalFree(publicKeyInfo);

        /*
         * Now use hKey to encrypt whatever you need.
         */

        // Open plain text file
        //_tprintf(_T("CreateFile...\n"));
        if ((hPlainFile = CreateFile(strPlainFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL)) == INVALID_HANDLE_VALUE)
        {
            // Error
            //_tprintf(_T("CreateFile error 0x%x\n"), GetLastError());
            return 1;
        }

        // Get file size
        //_tprintf(_T("GetFileSize...\n"));
        if ((dwDataLen = GetFileSize(hPlainFile, NULL)) == INVALID_FILE_SIZE)
        {
            // Error
            //_tprintf(_T("GetFileSize error 0x%x\n"), GetLastError());
            return 1;
        }

        // Create a buffer for the plain text
        //_tprintf(_T("malloc...\n"));
        if (!(pbData = (BYTE *)malloc(dwDataLen)))
        {
            // Error
            //_tprintf(_T("malloc error 0x%x\n"), GetLastError());
            return 1;
        }

        // Read plain text
        //_tprintf(_T("ReadFile...\n"));
        if (!ReadFile(hPlainFile, pbData, dwDataLen, &dwDataLen, NULL))
        {
            // Error
            //_tprintf(_T("ReadFile error 0x%x\n"), GetLastError());
            return 1;
        }

        // Get lenght for encrypted data
        if (!CryptEncrypt(hKey, NULL, TRUE, 0, NULL, &dwEncryptedLen, 0))
        {
            // Error
            //_tprintf(_T("CryptEncrypt error 0x%x\n"), GetLastError());
            return 1;
        }

        // Create a buffer for encrypted data
        //_tprintf(_T("malloc...\n"));
        if (!(pbData = (BYTE *)realloc(pbData, dwEncryptedLen)))
        {
            // Error
            //_tprintf(_T("malloc error 0x%x\n"), GetLastError());
            return 1;
        }

        // Encrypt data
        if (!CryptEncrypt(hKey, NULL, TRUE, 0, pbData, &dwDataLen, dwEncryptedLen))
        {
            // Error
            //_tprintf(_T("CryptEncrypt error 0x%x\n"), GetLastError());
            return 1;
        }

        // Create a file to save the encrypted data
        //_tprintf(_T("CreateFile...\n"));
        if ((hEncryptedFile = CreateFile(strEncryptedFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
        {
            // Error
            //_tprintf(_T("CreateFile error 0x%x\n"), GetLastError());
            return 1;
        }

        // Write the public key to the file
        //_tprintf(_T("WriteFile...\n"));
        if (!WriteFile(hEncryptedFile, (LPCVOID)pbData, dwDataLen, &lpNumberOfBytesWritten, NULL))
        {
            // Error
            //_tprintf(_T("WriteFile error 0x%x\n"), GetLastError());
            return 1;
        }
        return 0;
    }

    __finally
    {
        // Clean up
        if (!pbPublicKey) {
            //_tprintf(_T("free...\n"));
            free(pbPublicKey);
        }

        if (!pbData) {
            //_tprintf(_T("free...\n"));
            free(pbData);
        }

        if (hPublicKeyFile) {
            //_tprintf(_T("CloseHandle...\n"));
            CloseHandle(hPublicKeyFile);
        }

        if (hPlainFile) {
            //_tprintf(_T("CloseHandle...\n"));
            CloseHandle(hPlainFile);
        }

        if (hEncryptedFile) {
            //_tprintf(_T("CloseHandle...\n"));
            CloseHandle(hEncryptedFile);
        }

        if (hKey) {
            //_tprintf(_T("CryptDestroyKey...\n"));
            CryptDestroyKey(hKey);
        }

        if (hCryptProv) {
            //_tprintf(_T("CryptReleaseContext...\n"));
            CryptReleaseContext(hCryptProv, 0);
        }
    }
}
// End of Encrypt

// Encrypt string
int RSA::EncryptStringWithPublicKey(LPCWSTR szPemPublicKey, BYTE* pbDataPlaintext, BYTE* pbDataCiphertext)
{
    // Variables
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hKey = NULL;
    DWORD dwPublicKeyLen = 0;
    DWORD dwDataLen = 0;
    DWORD dwEncryptedLen = 0;
    BYTE* pbPublicKey = NULL;
    //BYTE* pbData = NULL;
    HANDLE hPublicKeyFile = NULL;
    HANDLE hEncryptedFile = NULL;
    HANDLE hPlainFile = NULL;
    DWORD lpNumberOfBytesWritten = 0;

    int readLen;
    BYTE derPubKey[2048];
    DWORD derPubKeyLen = 2048;
    CERT_PUBLIC_KEY_INFO *publicKeyInfo;
    DWORD publicKeyInfoLen;
    HANDLE hFile;

    if (!CryptStringToBinary(szPemPublicKey, 0, CRYPT_STRING_BASE64HEADER, derPubKey, &derPubKeyLen, NULL, NULL))
    {
        //fprintf(stderr, "CryptStringToBinary failed. Err: %d\n", GetLastError());
        return -1;
    }

    /*
    * Decode from DER format to CERT_PUBLIC_KEY_INFO
    */
    if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, derPubKey, derPubKeyLen, CRYPT_ENCODE_ALLOC_FLAG, NULL, &publicKeyInfo, &publicKeyInfoLen))
    {
        //fprintf(stderr, "CryptDecodeObjectEx 1 failed. Err: %p\n", GetLastError());
        return -1;
    }

    /*
    * Acquire context
    */
    if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
    {
        {
            //printf("CryptAcquireContext failed - err=0x%x.\n", GetLastError());
            return -1;
        }
    }

    /*
    * Import the public key using the context
    */
    if (!CryptImportPublicKeyInfo(hCryptProv, X509_ASN_ENCODING, publicKeyInfo, &hKey))
    {
        //fprintf(stderr, "CryptImportPublicKeyInfo failed. error: %d\n", GetLastError());
        return -1;
    }
    LocalFree(publicKeyInfo);

    /*
    * Now use hKey to encrypt whatever you need.
    */

    // Create a buffer for the plain text
        //_tprintf(_T("malloc...\n"));
    if (!(pbDataPlaintext = (BYTE *)malloc(dwDataLen)))
    {
        // Error
        _tprintf(_T("malloc error 0x%x\n"), GetLastError());
        return 1;
    }



    // Get lenght for encrypted data
    if (!CryptEncrypt(hKey, NULL, TRUE, 0, NULL, &dwEncryptedLen, 0))
    {
        // Error
        _tprintf(_T("CryptEncrypt error 0x%x\n"), GetLastError());
        return 1;
    }

    // Create a buffer for encrypted data
    //_tprintf(_T("malloc...\n"));
    if (!(pbDataPlaintext = (BYTE *)realloc(pbDataPlaintext, dwEncryptedLen)))
    {
        // Error
        _tprintf(_T("malloc error 0x%x\n"), GetLastError());
        return 1;
    }

    // Encrypt data
    if (!CryptEncrypt(hKey, NULL, TRUE, 0, pbDataPlaintext, &dwDataLen, dwEncryptedLen))
    {
        // Error
        _tprintf(_T("CryptEncrypt error 0x%x\n"), GetLastError());
        return 1;
    }

    printf("S: %s\n", pbDataPlaintext);

    // Clean up
    if (!pbPublicKey) {
        //_tprintf(_T("free...\n"));
        free(pbPublicKey);
    }

    if (!pbDataPlaintext) {
        //_tprintf(_T("free...\n"));
        free(pbDataPlaintext);
    }

    if (hPublicKeyFile) {
        //_tprintf(_T("CloseHandle...\n"));
        CloseHandle(hPublicKeyFile);
    }

    if (hPlainFile) {
        //_tprintf(_T("CloseHandle...\n"));
        CloseHandle(hPlainFile);
    }

    if (hEncryptedFile) {
        //_tprintf(_T("CloseHandle...\n"));
        CloseHandle(hEncryptedFile);
    }

    if (hKey) {
        //_tprintf(_T("CryptDestroyKey...\n"));
        CryptDestroyKey(hKey);
    }

    if (hCryptProv) {
        //_tprintf(_T("CryptReleaseContext...\n"));
        CryptReleaseContext(hCryptProv, 0);
    }
}
// End of Encrypt

// Decrypt file
int RSA::DecryptFileWithPrivateKey(LPCWSTR szPemPrivateKey, _TCHAR* strEncryptedFile, _TCHAR* strPlainFile)
{
    // Variables
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hKey = NULL;
    DWORD dwPrivateKeyLen = 0;
    DWORD dwDataLen = 0;
    BYTE* pbPrivateKey = NULL;
    BYTE* pbData = NULL;
    HANDLE hPrivateKeyFile = NULL;
    HANDLE hEncryptedFile = NULL;
    HANDLE hPlainFile = NULL;
    DWORD lpNumberOfBytesWritten = 0;

    BYTE derPrivateKey[2048];
    DWORD derPrivateKeyLen = 2048;
    CRYPT_PRIVATE_KEY_INFO *privateKeyInfo = NULL;
    DWORD privateKeyInfoLen = 0;
    HANDLE hFile = NULL;

    __try
    {
        // Acquire access to key container
        /*
         * Convert from PEM format to DER format - removes header and footer and decodes from base64
         */
        if (!CryptStringToBinary(szPemPrivateKey, 0, CRYPT_STRING_BASE64HEADER, derPrivateKey, &derPrivateKeyLen, NULL, NULL))
        {
            //fprintf(stderr, "CryptStringToBinary failed. Err: %d\n", GetLastError());
            return -1;
        }

        /*
         * Decode from DER format to CERT_PUBLIC_KEY_INFO
         */
        if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, derPrivateKey, derPrivateKeyLen, CRYPT_ENCODE_ALLOC_FLAG, NULL, &privateKeyInfo, &privateKeyInfoLen))
        {
            //fprintf(stderr, "CryptDecodeObjectEx 1 failed. Err: %p\n", GetLastError());
            return -1;
        }

        /*
         * Acquire context
         */
        if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
        {
            {
                //printf("CryptAcquireContext failed - err=0x%x.\n", GetLastError());
                return -1;
            }
        }

        /*
         * Import the public key using the context
         */
        if (!CryptImportKey(hCryptProv, X509_ASN_ENCODING, privateKey, &hKey))
        {
            //fprintf(stderr, "CryptImportPublicKeyInfo failed. error: %d\n", GetLastError());
            return -1;
        }
        LocalFree(privateKeyInfo);
        // Import private key
        _tprintf(_T("CryptImportKey...\n"));
        if (!CryptImportKey(hCryptProv, pbPrivateKey, dwPrivateKeyLen, 0, 0, &hKey))
        {
            // Error
            _tprintf(_T("CryptImportKey error 0x%x\n"), GetLastError());
            return 1;
        }

        // Open encrypted file
        _tprintf(_T("CreateFile...\n"));
        if ((hEncryptedFile = CreateFile(
            strEncryptedFile,
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_FLAG_SEQUENTIAL_SCAN,
            NULL
        )) == INVALID_HANDLE_VALUE)
        {
            // Error
            _tprintf(_T("CreateFile error 0x%x\n"), GetLastError());
            return 1;
        }

        // Get file size
        _tprintf(_T("GetFileSize...\n"));
        if ((dwDataLen = GetFileSize(hEncryptedFile, NULL)) == INVALID_FILE_SIZE)
        {
            // Error
            _tprintf(_T("GetFileSize error 0x%x\n"), GetLastError());
            return 1;
        }

        // Create a buffer for the encrypted data
        _tprintf(_T("malloc...\n"));
        if (!(pbData = (BYTE *)malloc(dwDataLen)))
        {   // Error
            _tprintf(_T("malloc error 0x%x\n"), GetLastError());
            return 1;
        }

        // Read encrypted data
        _tprintf(_T("ReadFile...\n"));
        if (!ReadFile(hEncryptedFile, pbData, dwDataLen, &dwDataLen, NULL))
        {
            // Error
            _tprintf(_T("ReadFile error 0x%x\n"), GetLastError());
            return 1;
        }

        // Get lenght for plain text
        if (!CryptDecrypt(hKey, NULL, TRUE, 0, pbData, &dwDataLen))
        {
            // Error
            _tprintf(_T("CryptDecrypt error 0x%x\n"), GetLastError());
            return 1;
        }

        // Create a file to save the plain text
        _tprintf(_T("CreateFile...\n"));
        if ((hPlainFile = CreateFile(
            strPlainFile,
            GENERIC_WRITE,
            0,
            NULL,
            CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        )) == INVALID_HANDLE_VALUE)
        {
            // Error
            _tprintf(_T("CreateFile error 0x%x\n"), GetLastError());
            return 1;
        }

        // Write the plain text the file
        _tprintf(_T("WriteFile...\n"));
        if (!WriteFile(
            hPlainFile,
            (LPCVOID)pbData,
            dwDataLen,
            &lpNumberOfBytesWritten,
            NULL
        ))
        {
            // Error
            _tprintf(_T("WriteFile error 0x%x\n"), GetLastError());
            return 1;
        }

        return 0;
    }

    __finally
    {
        // Clean up
        if (!pbPrivateKey) {
            _tprintf(_T("free...\n"));
            free(pbPrivateKey);
        }

        if (!pbData) {
            _tprintf(_T("free...\n"));
            free(pbData);
        }

        if (hPrivateKeyFile) {
            _tprintf(_T("CloseHandle...\n"));
            CloseHandle(hPrivateKeyFile);
        }

        if (hEncryptedFile) {
            _tprintf(_T("CloseHandle...\n"));
            CloseHandle(hEncryptedFile);
        }

        if (hPlainFile) {
            _tprintf(_T("CloseHandle...\n"));
            CloseHandle(hPlainFile);
        }

        if (hKey) {
            _tprintf(_T("CryptDestroyKey...\n"));
            CryptDestroyKey(hKey);
        }

        if (hCryptProv) {
            _tprintf(_T("CryptReleaseContext...\n"));
            CryptReleaseContext(hCryptProv, 0);
        }
    }
}
// End of Decrypt

// Decrypt string
int RSA::DecryptStringWithPrivateKey(LPCWSTR szPemPrivateKey, BYTE* pbDataCiphertext, BYTE* pbDataPlaintext)
{

}

1 个答案:

答案 0 :(得分:0)

我可以自己修复cryptoFileWithPrivateKey()函数,因此我希望它可以帮助其他人解决相同的问题。更新的代码如下:

现在我只是坚持的字符串加密/解密功能... 也许有人会帮忙...

// Decrypt file
int RSA::DecryptFileWithPrivateKey(LPCWSTR szPemPrivateKey, _TCHAR* strEncryptedFile, _TCHAR* strPlainFile)
{
    // Variables
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hKey = NULL;
    DWORD dwPrivateKeyLen = 0;
    DWORD dwDataLen = 0;
    BYTE* pbPrivateKey = NULL;
    BYTE* pbData = NULL;
    HANDLE hPrivateKeyFile = NULL;
    HANDLE hEncryptedFile = NULL;
    HANDLE hPlainFile = NULL;
    DWORD lpNumberOfBytesWritten = 0;

    BYTE derPrivateKey[2048];
    DWORD derPrivateKeyLen = 2048;

    DWORD dwBufferLen = 0, cbKeyBlob = 0, cbSignature = 0, i;
    LPBYTE pbBuffer = NULL, pbKeyBlob = NULL, pbSignature = NULL;
    HCRYPTPROV hProv = NULL;
    HCRYPTHASH hHash = NULL;

    __try
    {
        if (!CryptStringToBinary(szPemPrivateKey, 0, CRYPT_STRING_BASE64HEADER, NULL, &dwBufferLen, NULL, NULL))
        {
            printf("Failed to convert BASE64 private key. Error 0x%.8X\n", GetLastError());
            return -1;
        }

        pbBuffer = (LPBYTE)LocalAlloc(0, dwBufferLen);
        if (!CryptStringToBinary(szPemPrivateKey, 0, CRYPT_STRING_BASE64HEADER, pbBuffer, &dwBufferLen, NULL, NULL))
        {
            printf("Failed to convert BASE64 private key. Error 0x%.8X\n", GetLastError());
            return -1;
        }

        if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, pbBuffer, dwBufferLen, 0, NULL, NULL, &cbKeyBlob))
        {
            printf("Failed to parse private key. Error 0x%.8X\n", GetLastError());
            return -1;
        }

        pbKeyBlob = (LPBYTE)LocalAlloc(0, cbKeyBlob);
        if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, pbBuffer, dwBufferLen, 0, NULL, pbKeyBlob, &cbKeyBlob))
        {
            printf("Failed to parse private key. Error 0x%.8X\n", GetLastError());
            return -1;
        }

        // Create a temporary and volatile CSP context in order to import
        // the key and use for signing
        if (!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
        {
            printf("CryptAcquireContext failed with error 0x%.8X\n", GetLastError());
            return -1;
        }

        if (!CryptImportKey(hProv, pbKeyBlob, cbKeyBlob, NULL, 0, &hKey))
        {
            printf("CryptImportKey for private key failed with error 0x%.8X\n", GetLastError());
            return -1;
        }


        // Open encrypted file
        _tprintf(_T("CreateFile...\n"));
        if ((hEncryptedFile = CreateFile(
            strEncryptedFile,
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_FLAG_SEQUENTIAL_SCAN,
            NULL
        )) == INVALID_HANDLE_VALUE)
        {
            // Error
            _tprintf(_T("CreateFile error 0x%x\n"), GetLastError());
            return 1;
        }
        // Get file size
        _tprintf(_T("GetFileSize...\n"));
        if ((dwDataLen = GetFileSize(hEncryptedFile, NULL)) == INVALID_FILE_SIZE)
        {
            // Error
            _tprintf(_T("GetFileSize error 0x%x\n"), GetLastError());
            return 1;
        }
        // Create a buffer for the encrypted data
        _tprintf(_T("malloc...\n"));
        if (!(pbData = (BYTE *)malloc(dwDataLen)))
        {
            // Error
            _tprintf(_T("malloc error 0x%x\n"), GetLastError());
            return 1;
        }
        // Read encrypted data
        _tprintf(_T("ReadFile...\n"));
        if (!ReadFile(hEncryptedFile, pbData, dwDataLen, &dwDataLen, NULL))
        {
            // Error
            _tprintf(_T("ReadFile error 0x%x\n"), GetLastError());
            return 1;
        }
        // Get lenght for plain text
        if (!CryptDecrypt(hKey, NULL, TRUE, 0, pbData, &dwDataLen))
        {
            // Error
            _tprintf(_T("CryptDecrypt error 0x%x\n"), GetLastError());
            return 1;
        }
        // Create a file to save the plain text
        _tprintf(_T("CreateFile...\n"));
        if ((hPlainFile = CreateFile(
            strPlainFile,
            GENERIC_WRITE,
            0,
            NULL,
            CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        )) == INVALID_HANDLE_VALUE)
        {
            // Error
            _tprintf(_T("CreateFile error 0x%x\n"), GetLastError());
            return 1;
        }
        // Write the plain text the file
        _tprintf(_T("WriteFile...\n"));
        if (!WriteFile(
            hPlainFile,
            (LPCVOID)pbData,
            dwDataLen,
            &lpNumberOfBytesWritten,
            NULL
        ))
        {
            // Error
            _tprintf(_T("WriteFile error 0x%x\n"), GetLastError());
            return 1;
        }
        return 0;
    }
    __finally
    {
        // Clean up
        if (!pbPrivateKey) {
            _tprintf(_T("free...\n"));
            free(pbPrivateKey);
        }
        if (!pbData) {
            _tprintf(_T("free...\n"));
            free(pbData);
        }
        if (hPrivateKeyFile) {
            _tprintf(_T("CloseHandle...\n"));
            CloseHandle(hPrivateKeyFile);
        }
        if (hEncryptedFile) {
            _tprintf(_T("CloseHandle...\n"));
            CloseHandle(hEncryptedFile);
        }
        if (hPlainFile) {
            _tprintf(_T("CloseHandle...\n"));
            CloseHandle(hPlainFile);
        }
        if (hKey) {
            _tprintf(_T("CryptDestroyKey...\n"));
            CryptDestroyKey(hKey);
        }
        if (hCryptProv) {
            _tprintf(_T("CryptReleaseContext...\n"));
            CryptReleaseContext(hCryptProv, 0);
        }
    }
}
// End of Decrypt