密码学 - 单表代换密码破解



近年来,技术已融入日常生活。它简化了账单支付和网上购物等任务。然而,人们经常在网上账户中存储敏感信息,却意识不到黑客可以轻松访问这些信息。为了理解这种漏洞,必须以黑客的心态去认识他们如何绕过公司采用的安全措施。

在网络安全领域,虽然公司负责 50% 的防护,但另一半则取决于用户以及他们对所提供安全工具的有效使用。黑客会使用诸如频率分析、暴力破解和网络钓鱼等技术。频率分析是一种用于破解单表代换密码的基本密码分析方法。

破解单表代换密码的方法

以下是一些破解或密码分析单表代换密码的方法:

  • 频率分析 - 不同的字母在英语中出现的频率不同。“E”是最常见的字母。研究字母在密文中出现的频率可以帮助你找出哪个字母可能代表“E”。一旦你知道了这一点,你就可以找出其他字母。

  • 模式识别 - 查看密文中是否存在重复出现的序列。一些字母组合,例如“TH”或“ING”,在英语中出现频率很高。如果你注意到这些组合,你可以猜测它们分别代表哪些字母。

  • 猜测和检查 - 根据上下文进行合理的猜测。例如:如果你怀疑一个单词是“THE”,猜测可能代表“T”、“H”和“E”的字母。利用这一点来揭示其他字母。

  • 已知明文攻击 - 如果你同时拥有原始消息(明文)和加密消息(密文),你可以利用这些信息来找出加密密钥。这种方法非常有效,但通常需要更多资源。

  • 暴力破解 - 作为最后的手段,尝试所有可能的字母组合,直到找到正确的组合。这种方法需要大量时间,通常只适用于短消息。

使用 Python 实现

单表代换密码使用固定的替换来加密整个消息。一个利用 Python 字典和 JSON 对象的单表代换密码。通过使用此字典,我们可以加密字母并将相应的字母作为值存储在 JSON 中。以下程序以类的形式创建了一个单表代换程序,其中包含所有加密和解密函数。

示例

from string import ascii_letters, digits
from random import shuffle

def random_monoalpha_cipher(pool=None):
   if pool is None:
      pool = ascii_letters + digits
   original_pool = list(pool)
   shuffled_pool = list(pool)
   shuffle(shuffled_pool)
   return dict(zip(original_pool, shuffled_pool))

def inverse_monoalpha_cipher(monoalpha_cipher):
   inverse_monoalpha = {}
   for key, value in monoalpha_cipher.items():
      inverse_monoalpha[value] = key
   return inverse_monoalpha

def encrypt_with_monoalpha(message, monoalpha_cipher):
   encrypted_message = []
   for letter in message:
      encrypted_message.append(monoalpha_cipher.get(letter, letter))
   return ''.join(encrypted_message)

def decrypt_with_monoalpha(encrypted_message, monoalpha_cipher):
   return encrypt_with_monoalpha(
      encrypted_message,
      inverse_monoalpha_cipher(monoalpha_cipher)
   )

# Generate a random monoalphabetic cipher
cipher = random_monoalpha_cipher()
print("Cipher:", cipher)

# Encrypt a message
message = 'Hello all you hackers out there!'
encrypted = encrypt_with_monoalpha(message, cipher)
print("Encrypted:", encrypted)

# Decrypt the message
decrypted = decrypt_with_monoalpha(encrypted, cipher)
print("Decrypted:", decrypted)

当你实现上面给出的代码时,你将得到以下输出。

输入/输出

Monoalphabetic Output

因此,你可以使用定义的键值组合破解单表代换密码,将密文转换为明文。

使用 Java 实现

下面提供的 Java 代码具有与我们上面提到的 Python 代码类似的功能。它可以创建一个随机的单表代换密码,使用该密码加密消息,并解密加密的消息。请参阅下面的代码:

示例

import java.util.*;

public class MonoalphabeticCipher {
   public static Map<Character, Character> randomMonoalphaCipher(String pool) {
      List<Character> originalChar = new ArrayList<>();
      List<Character> ShuffledChar = new ArrayList<>();

      for (char c : pool.toCharArray()) {
         originalChar.add(c);
         ShuffledChar.add(c);
      }

      Collections.shuffle(ShuffledChar);

      Map<Character, Character> cipher = new HashMap<>();
      for (int i = 0; i < originalChar.size(); i++) {
      cipher.put(originalChar.get(i), ShuffledChar.get(i));
      }

      return cipher;
   }

   public static Map<Character, Character> inverseCharCipher(Map<Character, Character> monoalphaCipher) {
      Map<Character, Character> inverseChar = new HashMap<>();
      for (Map.Entry<Character, Character> entry : monoalphaCipher.entrySet()) {
         inverseChar.put(entry.getValue(), entry.getKey());
      }
      return inverseChar;
   }

   public static String encryptMessage(String message, Map<Character, Character> monoalphaCipher) {
      StringBuilder etMsg = new StringBuilder();
      for (char letter : message.toCharArray()) {
         etMsg.append(monoalphaCipher.getOrDefault(letter, letter));
      }
      return etMsg.toString();
   }

   public static String decryptMessage(String etMsg, Map<Character, Character> monoalphaCipher) {
      return encryptMessage(etMsg, inverseCharCipher(monoalphaCipher));
   }

   public static void main(String[] args) {
      String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
      Map<Character, Character> cipher = randomMonoalphaCipher(characters);
      System.out.println("Cipher: " + cipher);

      String message = "Hello all you hackers out there!";
      String encrypted = encryptMessage(message, cipher);
      System.out.println("Encrypted: " + encrypted);

      String decrypted = decryptMessage(encrypted, cipher);
      System.out.println("Decrypted: " + decrypted);
   }
}

以下是上面示例的输出:

输入/输出

Monoalphabetic Output
广告