密码学 - 文件加密



文件加密是一种加密方法,它将您的文件转换为密文或不可读数据。使用此方法可确保即使未经授权的人员访问您的数据,也无法在没有解密密钥的情况下读取内容。

简单来说,加密文件为保护敏感信息免受外部人员侵害增加了额外的安全层。

在本章中,我们将了解不同的加密技术来加密文件数据。所以让我们深入探讨一下。

文件加密的基本方法

任何加密方法都有其自身的一套特征和优势。因此,选择最适合公司的加密方法非常重要。这些方法包括:

对称加密

对称加密是一种流行的加密方法,它使用相同的密钥来加密和解密数据。虽然使用单个密钥来加密和解密信息看起来已经过时,但如果执行得当,它非常高效。

对称加密的密钥在发送方和预期接收方之间共享并保密。当文件被加密时,加密密钥将明文转换为密文。接收方使用相同的密钥来反转解密文件的过程并恢复原始明文。

非对称加密

非对称加密,也称为公钥加密,是在加密文件时对称加密的替代方案。非对称加密使用两个独立但数学相关的密钥。公钥被分发,但私钥被隐藏,只有所有者知道。在加密文件时,发送方使用接收方的公钥将明文转换为密文。然后,接收方使用其私钥解密密文以获取原始明文。

混合加密

对于希望获得对称和非对称加密优势的公司来说,混合加密是一个完美的选择。该技术首先为每个文件或会话创建一个唯一的对称密钥。然后使用对称密钥加密文件,这提供了快速有效的加密。数据不是使用对称密钥而是使用接收方的非对称加密公钥进行加密。然后传输加密文件以及加密的对称密钥。如果接收方拥有正确的私钥,他们可以使用对称密钥来解密文件。

实现(加密文件)

现在我们将尝试使用不同的编程语言(如 Python、Java、C++ 等)来实现文件加密。因此,借助不同的编程语言来加密文件是学习加密和练习编码技能的最佳方法。以下是如何使用 Python、Java 和 C++ 加密文件的简单示例:

使用 Python

此代码展示了如何在 Python 中使用 cryptography 库中提供的 Fernet 对称加密方法进行文件加密。在此代码中,我们将提供一个作为输入的文本文件,我们需要对其进行加密。加密后,我们将获得一个加密文件,其中内容使用对称加密进行加密。

因此,请参阅以下使用 Python 的 Fernet 方法的实现

from cryptography.fernet import Fernet

# Generate a key
key = Fernet.generate_key()
cipher_suite = Fernet(key)

# Read the file
with open('plain_text.txt', 'rb') as f:
   plaintext = f.read()

# Encrypt the file
encrypted_text = cipher_suite.encrypt(plaintext)

# Write the encrypted file
with open('encrypted_file.txt', 'wb') as f:
   f.write(encrypted_text)
    
# Print message after file is encrypted
print("File encrypted successfully.")

输出

File encrypted successfully.

请参阅下面的输出图像,其中显示了 plain_text.txt 和 encrypted_file.txt 文件。

使用 Java

在此 Java 代码中,我们将使用 AES 加密算法在 ECB 模式下执行文件加密。因此,基本上我们需要加密给定的文本文件。并且代码将使用 Files.readAllBytes() 方法将名为“plain_text.txt”的文件的内容读入字节数组。并且从加密步骤获得的加密字节数组将使用 Files.write() 方法写入名为“encrypted_file.txt”的新文件。

因此,请参阅以下 Java 中的实现:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.spec.KeySpec;
import java.util.Base64;

public class Program {

   public static void main(String[] args) throws Exception {
      // Read the file
      byte[] plaintext = Files.readAllBytes(Paths.get("plain_text.txt"));

      // Generate a key
      String password = "your_password";
      byte[] salt = "your_salt".getBytes();
      SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
      KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
      SecretKey tmp = factory.generateSecret(spec);
      SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

      // Encrypt the file
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
      cipher.init(Cipher.ENCRYPT_MODE, secret);
      byte[] encryptedText = cipher.doFinal(plaintext);

      // Write the encrypted file
      Files.write(Paths.get("encrypted_file.txt"), encryptedText);
      System.out.println("File is encrypted successfully!");
   }
}

输入/输出

File is encrypted successfully!    

使用 Javascript

在 JavaScript 中,您可以使用 Web Crypto API 在浏览器环境中执行文件加密。下面是一个使用 JavaScript 加密文件的示例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Encryption</title>
<style>
   body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #f4f4f4;
   }

   #container {
      text-align: center;
   }

   #fileLabel {
      padding: 10px 20px;
      background-color: #007bff;
      color: #fff;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      transition: background-color 0.3s;
   }

   #fileLabel:hover {
      background-color: #0056b3;
   }

   #fileInput {
      display: none;
   }

   #fileName {
      margin-top: 10px;
   }

   #encryptButton {
      margin-top: 20px;
      padding: 10px 20px;
      background-color: #28a745;
      color: #fff;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      transition: background-color 0.3s;
   }

   #encryptButton:hover {
      background-color: #218838;
   }
</style>
</head>
<body>
<div id="container">
   <label for="fileInput" id="fileLabel">Choose File</label>
   <input type="file" id="fileInput" onchange="displayFileName()">
   <div id="fileName"></div>
   <button id="encryptButton" onclick="encryptFile()">Encrypt File</button>
</div>
<script>
function displayFileName() {
   const fileInput = document.getElementById('fileInput');
   const fileName = document.getElementById('fileName');
   fileName.textContent = fileInput.files[0].name;
}

async function encryptFile() {
   const fileInput = document.getElementById('fileInput');
   const file = fileInput.files[0];
   if (!file) {
      alert('Please select a file.');
      return;
   }

   const reader = new FileReader();
   reader.onload = async function(event) {
      const data = event.target.result;
      const password = 'your_password';

      const encodedData = new TextEncoder().encode(data);
      const encodedPassword = new TextEncoder().encode(password);

      const key = await crypto.subtle.importKey(
         'raw',
         encodedPassword,
         { name: 'PBKDF2' },
         false,
         ['deriveKey']
      );

      const derivedKey = await crypto.subtle.deriveKey(
         { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 1000, hash: 'SHA-256' },
         key,
         { name: 'AES-GCM', length: 256 },
         true,
         ['encrypt', 'decrypt']
      );

      const iv = crypto.getRandomValues(new Uint8Array(12));
      const encryptedData = await crypto.subtle.encrypt(
         { name: 'AES-GCM', iv: iv },
         derivedKey,
         encodedData
      );

      const encryptedBlob = new Blob([iv, new Uint8Array(encryptedData)]);
      const encryptedFile = new File([encryptedBlob], 'encrypted_file.txt', { type: 'text/plain' });

      const downloadLink = document.createElement('a');
      downloadLink.href = URL.createObjectURL(encryptedFile);
      downloadLink.download = 'encrypted_file.txt';
      downloadLink.click();
   };

   reader.readAsBinaryString(file);
}
</script>
</body>
</html>

输入/输出

运行上述代码后,我们将看到以下页面,其中将有两个按钮,第一个按钮是“选择文件”,我们可以通过它选择要加密的文件。第二个按钮是加密上传的文件,因此它将要求将加密文件下载到我们的系统中。因此,我们可以看到加密文件,如下面的输出所示。

Javascript File Encryption
广告