溫馨提示×

如何用C++實現Linux下的文件加密

小樊
46
2025-09-13 06:04:47
欄目: 編程語言

在Linux下使用C++實現文件加密,可以采用多種方法。以下介紹一種基于**AES(高級加密標準)**的對稱加密方法,并使用OpenSSL庫來簡化加密過程。AES是一種廣泛使用的對稱加密算法,安全性和效率都較高。

步驟概述

  1. 安裝OpenSSL開發庫
  2. 編寫C++代碼實現加密和解密
  3. 編譯并運行程序

1. 安裝OpenSSL開發庫

在開始編寫代碼之前,需要確保系統中安裝了OpenSSL的開發庫??梢允褂靡韵旅钸M行安裝:

對于基于Debian的系統(如Ubuntu):

sudo apt-get update
sudo apt-get install libssl-dev

對于基于Red Hat的系統(如CentOS):

sudo yum install openssl-devel

2. 編寫C++代碼

下面是一個使用OpenSSL庫實現AES加密和解密的示例程序:

#include <iostream>
#include <fstream>
#include <string>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <cstring>

// 加密函數
bool aes_encrypt(const std::string &input_file, const std::string &output_file, const std::string &password) {
    // 讀取密碼生成密鑰和IV
    unsigned char key[AES_KEYLEN_256];
    unsigned char iv[AES_BLOCK_SIZE];

    // 使用PBKDF2從密碼派生密鑰
    if (!PKCS5_PBKDF2_HMAC(password.c_str(), password.size(),
                          nullptr, 0,
                          10000, AES_KEYLEN_256,
                          EVP_sha256(), key)) {
        std::cerr << "密鑰派生失敗" << std::endl;
        return false;
    }

    // 生成隨機IV
    if (!RAND_bytes(iv, sizeof(iv))) {
        std::cerr << "生成IV失敗" << std::endl;
        return false;
    }

    // 打開輸入文件
    std::ifstream infile(input_file, std::ios::binary);
    if (!infile) {
        std::cerr << "無法打開輸入文件: " << input_file << std::endl;
        return false;
    }

    // 打開輸出文件
    std::ofstream outfile(output_file, std::ios::binary);
    if (!outfile) {
        std::cerr << "無法打開輸出文件: " << output_file << std::endl;
        return false;
    }

    // 寫入IV到輸出文件
    outfile.write(reinterpret_cast<const char*>(iv), sizeof(iv));

    AES_KEY enc_key;
    AES_set_encrypt_key(key, AES_KEYLEN_256, &enc_key);

    // 加密緩沖區
    const int buffer_size = 4096;
    unsigned char in_buf[buffer_size];
    unsigned char out_buf[buffer_size + AES_BLOCK_SIZE];

    while (infile.good()) {
        infile.read(reinterpret_cast<char*>(in_buf), sizeof(in_buf));
        std::streamsize bytes_read = infile.gcount();

        if (bytes_read > 0) {
            AES_encrypt(in_buf, out_buf, &enc_key);

            // 寫入加密數據
            outfile.write(reinterpret_cast<const char*>(out_buf), sizeof(out_buf));
        }
    }

    infile.close();
    outfile.close();
    return true;
}

// 解密函數
bool aes_decrypt(const std::string &input_file, const std::string &output_file, const std::string &password) {
    // 讀取IV
    unsigned char iv[AES_BLOCK_SIZE];

    // 打開輸入文件
    std::ifstream infile(input_file, std::ios::binary);
    if (!infile) {
        std::cerr << "無法打開輸入文件: " << input_file << std::endl;
        return false;
    }

    // 打開輸出文件
    std::ofstream outfile(output_file, std::ios::binary);
    if (!outfile) {
        std::cerr << "無法打開輸出文件: " << output_file << std::endl;
        return false;
    }

    // 讀取IV
    infile.read(reinterpret_cast<char*>(iv), sizeof(iv));

    // 讀取密碼生成密鑰
    unsigned char key[AES_KEYLEN_256];
    if (!PKCS5_PBKDF2_HMAC(password.c_str(), password.size(),
                          nullptr, 0,
                          10000, AES_KEYLEN_256,
                          EVP_sha256(), key)) {
        std::cerr << "密鑰派生失敗" << std::endl;
        return false;
    }

    AES_KEY dec_key;
    AES_set_decrypt_key(key, AES_KEYLEN_256, &dec_key);

    // 解密緩沖區
    const int buffer_size = 4096;
    unsigned char in_buf[buffer_size + AES_BLOCK_SIZE];
    unsigned char out_buf[buffer_size];

    while (infile.good()) {
        infile.read(reinterpret_cast<char*>(in_buf), sizeof(in_buf));
        std::streamsize bytes_read = infile.gcount();

        if (bytes_read > 0) {
            AES_decrypt(in_buf, out_buf, &dec_key);

            // 寫入解密數據
            outfile.write(reinterpret_cast<const char*>(out_buf), bytes_read);
        }
    }

    infile.close();
    outfile.close();
    return true;
}

int main(int argc, char *argv[]) {
    if (argc != 4) {
        std::cerr << "用法: " << argv[0] << " encrypt|decrypt 輸入文件 輸出文件 密碼" << std::endl;
        return 1;
    }

    std::string mode = argv[1];
    std::string input_file = argv[2];
    std::string output_file = argv[3];
    std::string password = argv[4];

    if (mode == "encrypt") {
        if (aes_encrypt(input_file, output_file, password)) {
            std::cout << "加密成功!" << std::endl;
        } else {
            std::cerr << "加密失??!" << std::endl;
            return 1;
        }
    }
    else if (mode == "decrypt") {
        if (aes_decrypt(input_file, output_file, password)) {
            std::cout << "解密成功!" << std::endl;
        } else {
            std::cerr << "解密失??!" << std::endl;
            return 1;
        }
    }
    else {
        std::cerr << "未知模式。使用encrypt或decrypt。" << std::endl;
        return 1;
    }

    return 0;
}

代碼說明

  1. 密鑰派生:使用PKCS5_PBKDF2_HMAC函數從用戶輸入的密碼派生出一個256位的AES密鑰。這增加了密碼的安全性,防止暴力破解。

  2. 初始化向量(IV):使用RAND_bytes生成一個隨機的IV,確保每次加密的結果不同,即使明文相同。

  3. 加密過程

    • 打開輸入文件和輸出文件。
    • 將IV寫入輸出文件的開頭,以便解密時使用。
    • 使用AES加密算法對數據進行分塊加密,并將加密后的數據寫入輸出文件。
  4. 解密過程

    • 打開加密文件和輸出文件。
    • 從加密文件中讀取IV。
    • 使用相同的密碼派生出密鑰。
    • 使用AES解密算法對數據進行分塊解密,并將解密后的數據寫入輸出文件。
  5. 主函數:通過命令行參數指定操作模式(encryptdecrypt)、輸入文件、輸出文件和密碼。

3. 編譯程序

使用g++編譯器,并鏈接OpenSSL庫:

g++ -o aes_encrypt aes_encrypt.cpp -lcrypto

4. 使用示例

加密文件

./aes_encrypt encrypt plaintext.txt encrypted.bin mypassword

解密文件

./aes_encrypt decrypt encrypted.bin decrypted.txt mypassword

注意事項

  1. 密碼管理:在實際應用中,避免將密碼硬編碼在源代碼中??梢钥紤]通過命令行參數、配置文件或安全存儲機制來管理密碼。

  2. 錯誤處理:示例代碼中對一些可能的錯誤進行了基本處理,但在生產環境中應添加更完善的錯誤檢查和日志記錄。

  3. 安全性:AES-256提供了很高的安全性,但整個加密方案的安全性還取決于密鑰管理和密碼的強度。確保使用復雜且難以猜測的密碼,并妥善保護密鑰。

  4. 依賴庫:本示例依賴于OpenSSL庫,確保在編譯和運行環境中已正確安裝并配置。

擴展

除了AES,OpenSSL還支持其他加密算法和模式(如CBC、GCM等)。根據需求選擇合適的算法和模式。例如,GCM模式提供了認證加密(AEAD),可以同時保證數據的機密性和完整性。

以下是使用GCM模式的簡要示例:

// 設置加密模式為GCM
AES_KEY enc_key;
AES_set_encrypt_key(key, AES_KEYLEN_256, &enc_key);
int len = AES_KEYLEN_256 / 8;
int tag_len = 16; // GCM標簽長度

// 加密
AES_GCM_encrypt(in_buf, out_buf, bytes_read,
               &enc_key, iv,
               tag_len,
               out_buf + bytes_read, // 輸出附加數據(AAD)
               sizeof(out_buf) - bytes_read - tag_len,
               nullptr, 0, // 無需額外的nonce,因為IV已經用作nonce
               nullptr);

// 解密
AES_GCM_decrypt(in_buf, out_buf, &dec_key, iv,
               tag_len,
               out_buf + bytes_read, // 輸出附加數據(AAD)
               sizeof(out_buf) - bytes_read - tag_len,
               in_buf + bytes_read,
               sizeof(in_buf) - bytes_read - tag_len,
               nullptr, 0,
               nullptr);

使用GCM模式時,需要額外處理認證標簽(Tag),以確保數據的完整性和真實性。

總結

通過以上步驟,您可以使用C++和OpenSSL庫在Linux環境下實現文件的AES加密和解密。根據具體需求選擇合適的加密算法和模式,并注意密鑰管理和密碼安全,以確保加密數據的安全性。

0
亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女