⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aescryptworkerthreads.cpp

📁 AES, 即Advanced Encryption Standard高级加密标准模块, 它是目前国际上最先进的加密技术, 是基于DES之后的最新发布的高段加密标准. 该标准由美国NIST(Nation
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                        result_code = in_buffered_file.ReadFile(buffer,
                                                                n,
                                                                &bytes_read);
                        if (result_code != ERROR_SUCCESS)
                        {
                            throw SystemErrorException(
                                        _T("Unable to read ") +
                                        in_file,
                                        result_code);
                        }

                        // XOR plain text block with previous encrypted
                        // output (i.e., use CBC)
                        for(i=0; i<16; i++)
                        {
                            buffer[i] ^= IV[i];
                        }

                        // Encrypt the contents of the buffer
                        aes_encrypt(&aes_ctx, buffer, buffer);
                        
                        // Concatenate the "text" as we compute the HMAC
                        sha256_update(&sha_ctx, buffer, 16);

                        // Write the encrypted block
                        result_code = out_buffered_file.WriteFile(
                                                            buffer,
                                                            16,
                                                            &bytes_written);
                        if (result_code != ERROR_SUCCESS)
                        {
                            throw SystemErrorException(
                                        _T("Unable to write to ") +
                                        out_file,
                                        result_code);
                        }
                        
                        // Update the IV (CBC mode)
                        memcpy(IV, buffer, 16);

                        // Update the UI when more than 250ms has passed
                        // or when there is no more data to read or
                        // when the next 1 percent of the file has been
                        // processed
                        current_percent =
                            (file_size.QuadPart - bytes_left) *
                                        100 / file_size.QuadPart;
                        if ((clock() - last_clock_time >
                            (CLOCKS_PER_SEC / 4)) ||
                            (bytes_left == 0) ||
                            (current_percent > last_percent))
                        {
                            // Update the progress bar
                            dlg.SendDlgItemMessage(
                                IDC_PROGRESSBAR,
                                PBM_SETPOS,
                                (WPARAM) current_percent,
                                0);
                            dlg.UpdateWindow();
                            DoMessageLoop();
                            if (dlg.abort_processing == true)
                            {
                                error_abort = true;
                                break;
                            }

                            last_clock_time = clock();
                            last_percent = current_percent;
                        }
                    }

                    if (error_abort == false)
                    {
                        // Write the HMAC
                        sha256_finish(&sha_ctx, digest);
                        sha256_starts(&sha_ctx);
                        sha256_update(&sha_ctx, opad, 64);
                        sha256_update(&sha_ctx, digest, 32);
                        sha256_finish(&sha_ctx, digest);
                        buffer[0] = (char) (file_size.LowPart & 0x0F);
                        result_code = out_buffered_file.WriteFile(
                                                            buffer,
                                                            1,
                                                            &bytes_written);
                        if (result_code == ERROR_SUCCESS)
                        {
                            result_code = out_buffered_file.WriteFile(
                                                            digest,
                                                            32,
                                                            &bytes_written);
                        }
                        if (result_code != ERROR_SUCCESS)
                        {
                            throw SystemErrorException(
                                        _T("Unable to write to ") +
                                        out_file,
                                        result_code);
                        }
                    }
                }
                catch(SystemErrorException e)
                {
                    ::ReportError(e.Message,e.Reason);
                    error_abort = true;
                }

                in_buffered_file.CloseFile();
                out_buffered_file.CloseFile();

                // We will attempt to cleanup, but we don't care if this
                // really works or not...
                if (error_abort == true)
                {
                    DeleteFile(out_file.c_str());
                    error_abort = true;
                }
            }
        }

        // Remove the filename from the list
        file_list->pop_front();
    }

    // For security reasons, erase the password
    memset(passwd, 0, sizeof(TCHAR) * MAX_PASSWD_LEN);
    
    // We processed the files, so we must have properly allocated hProv.
    // Now, release it.
    if (file_list->empty())
    {
        CryptReleaseContext(hProv, 0);
    }

    // Destroy the progress window
    dlg.DestroyWindow();

}

/*
 * DecryptFiles
 *
 * This function is called by the worker thread to decrypt a list of files.
 */
void AESCryptWorkerThreads::DecryptFiles(
                                StringList  *file_list,
                                TCHAR       *passwd)
{
    aes_context                 aes_ctx;
    sha256_context              sha_ctx;
    std::basic_string<TCHAR>    in_file;
    TCHAR                       out_file[MAX_PATH+1];
    TCHAR                       *p;
    BufferedFile                in_buffered_file,
                                out_buffered_file;
    DWORD                       result_code;
    unsigned char               IV[16];
    unsigned char               buffer[32], buffer2[32];
    unsigned char               iv_key[48];
    unsigned char               digest[32];
    LARGE_INTEGER               file_size; // 64-bit integer structure
    ULONGLONG                   bytes_left;
    int                         last_block_size;
    bool                        last_block_size_read;
    int                         i, j, n;
    DWORD                       bytes_written, bytes_read;
    unsigned char               ipad[64];
    unsigned char               opad[64];
    bool                        error_abort = false;
    ProgressDialog              dlg;
    unsigned                    version;
    unsigned                    footprint;
    clock_t                     last_clock_time;
    ULONGLONG                   last_percent, current_percent;

    // Passing a zero instructs the dialog to display
    // "Decrypting..."
    dlg.Create(NULL,0);

    // Walk through the list of files decrypting each
    while(!file_list->empty() && !error_abort)
    {
        // Get the filename
        in_file = file_list->front();
        _tcscpy_s(out_file, MAX_PATH, in_file.c_str());
        i = (int) _tcslen(out_file);
        if (i < 5)
        {
            ::ReportError(  _T("Invalid input file name: ") + in_file,
                            0);
            error_abort = true;
        }

        // Reset the progress bar (default range is 0..100)
        dlg.SendDlgItemMessage( IDC_PROGRESSBAR,
                                PBM_SETPOS,
                                0,
                                0);

        // Display the file name
        dlg.SetDlgItemText( IDC_FILENAME,
                            in_file.c_str());

        // Make sure the window is visible
        dlg.ShowWindow(SW_SHOWNORMAL);
        dlg.UpdateWindow();
        DoMessageLoop();
        
        // Remove the .aes extension (we hope ... gulp)
        p = out_file + i - 4;
        *p = _T('\0');

        if (error_abort == false)
        {
            result_code = in_buffered_file.OpenFile(in_file.c_str(),
                                                    false,
                                                    OPEN_EXISTING);
            if (result_code != ERROR_SUCCESS)
            {
                ::ReportError(  _T("Unable to open input file ") + in_file,
                                result_code);
                error_abort = true;
            }
        }

        if (error_abort == false)
        {
            result_code = out_buffered_file.OpenFile(   out_file,
                                                        true,
                                                        CREATE_NEW);
            if (result_code != ERROR_SUCCESS)
            {
                std::basic_string<TCHAR> message;

                // Close the input file
                in_buffered_file.CloseFile();

                message = _T("Unable to open output file ");
                message += out_file;
                ::ReportError(message, result_code);
                error_abort = true;
            }
            else
            {
                try
                {
                    // Determine the file size
                    result_code = in_buffered_file.FileSize(&file_size);
                    if (result_code != ERROR_SUCCESS)
                    {
                        throw SystemErrorException(
                                    _T("Unable to determine file size of ") +
                                    in_file,
                                    result_code);
                    }

                    if (file_size.QuadPart < FOOTPRINT_V0)
                    {
                        throw SystemErrorException(
                                    _T("Invalid input file ") +
                                    in_file + _T("\n File too short"),
                                    0);
                    }

                    // Read the file header
                    result_code = in_buffered_file.ReadFile(buffer,
                                                            5,
                                                            &bytes_read);
                    if (result_code != ERROR_SUCCESS)
                    {
                        throw SystemErrorException(
                                    _T("Unable to read ") +
                                    in_file,
                                    result_code);
                    }

                    if (buffer[0] != 'A' || buffer[1] != 'E' ||
                        buffer[2] != 'S')
                    {
                        throw SystemErrorException(
                                    _T("Invalid input file ") +
                                    in_file + _T("\n Invalid signature"),
                                    0);
                    }

                    version = (unsigned) buffer[3];
                    if (version > 1)
                    {
                        throw SystemErrorException(
                                    _T("Invalid input file ") +
                                    in_file + _T("\n Unsupported version"),
                                    0);
                    }

                    // How many bytes are left in the message
                    // (excludes header and HMAC)
                    if (version == 0)
                    {
                        bytes_left = file_size.QuadPart - FOOTPRINT_V0;

                        // Determine the number of octets in the last data block
                        last_block_size = (int) buffer[4] & 0x0F;
                        footprint = FOOTPRINT_V0;
                    }
                    else  // Must be a V1 file
                    {
                        if (file_size.QuadPart < FOOTPRINT_V1)
                        {
                            throw SystemErrorException(
                                        _T("Invalid input file ") +
                                        in_file + _T("\n File too short"),
                                        0);
                        }

                        bytes_left = file_size.QuadPart - FOOTPRINT_V1;
                        footprint = FOOTPRINT_V1;
                    }

                    // The message must be a multiple of 16 octets
                    if (bytes_left & 0x0F)
                    {
                        throw SystemErrorException(
                                    _T("Invalid input file ") +
                                    in_file + _T("\n Message length invalid"),
                                    0);
                    }

                    // Read the IV

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -