密码学 - 栅栏密码



栅栏法是一种基本的换位密码。它是一种加密过程,其中消息中的字母被重新排列以形成新的、看似无关的消息。这种方法的名称来自我们书写消息的方式。当使用栅栏法创建文本时,结果是一个之字形图案,其中每个字母在转到下一行之前都会被拼写出来。

为了使用栅栏法加密消息,必须将消息写入表格的第一行。此外,消息的第二个字母需要写在第二行。这个过程必须继续进行,直到所有消息的字母都被写入。最后,我们按行读取数据库以创建加密的消息。

现在让我们开始讨论如何解码消息。解密的第一步是根据加密消息的长度找到表格的行数。此外,我们必须将加密消息的第一个字母写在第一行,第二个字母写在第二行,依此类推。这个过程必须遵循,直到所有消息的字母都被写入。

总而言之,栅栏法的加密非常简单。它不能提供非常强的安全性。即使是具有基本密码学知识的人也可以轻松破解它。但是,在不需要高安全性的时候,它仍然可以用于简单的通信。

栅栏密码的工作原理?

本节将详细解释栅栏密码使用的加密和解密过程。

加密

为了使用栅栏密码解密消息,我们应该首先选择轨道数,使用该数字以之字形图案对角线写入消息,然后从左到右组合每条轨道上的字母。我们将在下面的示例中逐步讲解每个步骤。

让我们以“RAILFENCE”作为明文为例。现在假设有三个轨道或栅栏,也称为密钥。之字形图案的高度将由密钥决定。然后可以以之字形图案对角线从左到右写入消息:

Rail Fence Encryption

为了创建密文,我们将合并不同的行,在本例中为“RFEALECIN”。

解密

在我们开始解密过程之前,需要确定密文中行和列的数量。密文的长度等于列数。之后,我们需要确定加密了多少行——充当密钥。

现在我们知道了有多少行和列,我们可以构建表格并弄清楚字母应该放在哪里,因为栅栏密码以之字形图案从左到右对角线加密文本:

Rail Fence Decryption

星号 (*) 表示插入密文中的字母以创建明文的位置。从顶行(即第一“轨道”)开始,我们从左到右填写字母。直到所有星号位置都用密文中的字母填充,然后我们在下一轨道上继续此模式,依此类推:

Rail Fence Decryption

让我们完成上面的表格:

Rail Fence Decryption

最后,我们能够从左到右和从上到下组合字符以获得明文“RAILFENCE”。

实现

现在我们将使用 Python、Java、C++ 和 Javascript 实现栅栏密码。

使用 Python 实现

首先,我们将使用 Python 创建代码并实现栅栏密码。我们将创建两个不同的函数,一个用于加密,另一个用于解密。请看下面的代码:

示例

# Function to encrypt a message
def encrypt_rail_fence(plaintext, rails):

   # Create the matrix for cipher
   rail_matrix = [['\n' for i in range(len(plaintext))]
   for j in range(rails)]
	
   # Find the direction
   down_direction = False
   row, col = 0, 0
	
   for i in range(len(plaintext)):
		
      # Check the direction of flow
      # Reverse the direction if just filled the top or bottom rail
      if (row == 0) or (row == rails - 1):
         down_direction = not down_direction
		
         # Fill the corresponding alphabet
         rail_matrix[row][col] = plaintext[i]
         col += 1
		
         # Find the next row using direction flag
         if down_direction:
            row += 1
         else:
            row -= 1
	
   # Construct the cipher using the rail matrix
   cipher_text = []
   for i in range(rails):
      for j in range(len(plaintext)):
         if rail_matrix[i][j] != '\n':
            cipher_text.append(rail_matrix[i][j])
      return("" . join(cipher_text))
	
# Function to decrypt the cipher-text
# Function to decrypt the cipher-text
def decrypt_rail_fence(cipher, rails):

   # Create the matrix to cipher
   # plaintext - rows, length(cipher) - columns
   # Fill the rail matrix to distinguish filled spaces from blank ones
   rail_matrix = [['\n' for i in range(len(cipher))]
   for j in range(rails)]
	
   # Find the direction
   down_direction = None
   row, col = 0, 0
	
   for i in range(len(cipher)):
		
      # Check the direction of flow
      if row == 0:
         down_direction = True
      if row == rails - 1:
         down_direction = False
		
      # Place the cipher text in the rail matrix
      rail_matrix[row][col] = '*'
      col += 1
		
      # Find the next row using direction flag
      if down_direction:
         row += 1
      else:
         row -= 1
			
   # Reconstruct the rail matrix with cipher text
   index = 0
   for i in range(rails):
      for j in range(len(cipher)):
         if rail_matrix[i][j] == '*' and index < len(cipher):
            rail_matrix[i][j] = cipher[index]
            index += 1
				
   # Read the rail matrix in zig-zag manner to construct the resultant text
   result = []
   row, col = 0, 0
   for i in range(len(cipher)):
		
      # Check the direction of flow
      if row == 0:
         down_direction = True
      if row == rails - 1:
         down_direction = False
			
      # Add characters from the rail matrix to the result
      if rail_matrix[row][col] != '*':
         result.append(rail_matrix[row][col])
         col += 1
			
      # Find the next row using direction flag
      if down_direction:
         row += 1
      else:
         row -= 1
	
      return ''.join(result)

# Driver code
if __name__ == "__main__":
   print("First Encrypted Text: ", encrypt_rail_fence("Hello Tutorialspoint", 2))
   print("Second Encrypted Text: ", encrypt_rail_fence("Simple Text", 3))
   print("Third Encrypted Text: ", encrypt_rail_fence("I am great Cipher", 5))
   # Decryption of the cipher-text
   print("First Decrypted Text: ", decrypt_rail_fence("HloTtrasonel uoilpit", 2))
   print("Second Decrypted Text: ", decrypt_rail_fence("SleipeTxm t", 3))
   print("Third Decrypted Text: ", decrypt_rail_fence("Iar etear hmgCp i", 5))

以下是上述示例的输出:

输入/输出
First Encrypted Text:  HloTtrason
Second Encrypted Text:  S
Third Encrypted Text:  I
First Decrypted Text:  H
Second Decrypted Text:  S
Third Decrypted Text:  I

使用 Java 实现

现在我们将使用 Java 编程语言实现栅栏密码。我们将使用与 Python 中相同的 approach。在这里,我们将使用 Java 的 Arrays 库来实现栅栏矩阵。代码如下:

示例

import java.util.Arrays;
public class CustomRailFence {

   //Encrypt a message
   public static String encryptMessage(String plaintext, int rails) {

      // Create the matrix
      char[][] railMatrix = new char[rails][plaintext.length()];

      // Filling the rail matrix
      for (int i = 0; i < rails; i++)
      Arrays.fill(railMatrix[i], '\n');

      boolean dirDown = false;
      int row = 0, col = 0;

      for (int i = 0; i < plaintext.length(); i++) {

         // Check the direction of flow
         if (row == 0 || row == rails - 1)
         dirDown = !dirDown;

         // Fill the corresponding alphabet
         railMatrix[row][col++] = plaintext.charAt(i);

         // Find the next row using direction flag
         if (dirDown)
            row++;
         else
            row--;
      }
      // Now we can create the cipher 
      StringBuilder result = new StringBuilder();
      for (int i = 0; i < rails; i++)
      for (int j = 0; j < plaintext.length(); j++)
      if (railMatrix[i][j] != '\n')
      result.append(railMatrix[i][j]);

      return result.toString();
   }

    //Decrypt the ciphertext
   public static String decryptMessage(String cipher, int rails) {
      // Create the matrix 
      char[][] railMatrix = new char[rails][cipher.length()];

      // Filling the rail matrix 
      for (int i = 0; i < rails; i++)
      Arrays.fill(railMatrix[i], '\n');

      // Find the direction
      boolean dirDown = true;

      int row = 0, col = 0;

      // Mark the places with '*'
      for (int i = 0; i < cipher.length(); i++) {
         // Check the direction of flow
         if (row == 0)
            dirDown = true;
         if (row == rails - 1)
            dirDown = false;

         // Place the marker
         railMatrix[row][col++] = '*';

         // Find the next row 
         if (dirDown)
            row++;
         else
            row--;
      }

      // Now we can produce the fill the rail matrix
      int index = 0;
      for (int i = 0; i < rails; i++)
      for (int j = 0; j < cipher.length(); j++)
      if (railMatrix[i][j] == '*' && index < cipher.length())
         railMatrix[i][j] = cipher.charAt(index++);

      StringBuilder result = new StringBuilder();

      row = 0;
      col = 0;
      for (int i = 0; i < cipher.length(); i++) {
         // Check the direction of flow
         if (row == 0)
         dirDown = true;
         if (row == rails - 1)
         dirDown = false;

         // Place the marker
         if (railMatrix[row][col] != '*')
         result.append(railMatrix[row][col++]);

         // Find the next row using direction flag
         if (dirDown)
            row++;
         else
            row--;
      }
      return result.toString();
   }

   // Driver function
   public static void main(String[] args) {
      // Encryption
      System.out.println("The Encrypted Messages: ");
      System.out.println(encryptMessage("hello world", 2));
      System.out.println(encryptMessage("Simple Text", 4));
      System.out.println(encryptMessage("Java is great", 5));

      // Now decryption of the same cipher-text
      System.out.println("\nThe Decrypted Messages: ");
      System.out.println(decryptMessage("hlowrdel ol", 2));
      System.out.println(decryptMessage("S ieTmletpx", 4));
      System.out.println(decryptMessage("Jga rvseaia t", 5));
   }
}

以下是上述示例的输出:

输入/输出
The Encrypted Message: 
hlowrdel ol
S ieTmletpx
Jga rvseaia t

The Decrypted Messages: 
hello world
Simple Text
Java is great

使用 C++ 实现

在本节中,我们将构建C++代码来展示栅栏密码的过程。它将使用必要的库,如iostream和string。程序定义了两个主要函数,encryptMessage和decryptMessage,用于使用栅栏密码加密和解密消息。这些函数使用矩阵表示来创建栅栏密码算法,根据给定的轨数以锯齿形图案填充矩阵。以下是带有栅栏密码加密和解密函数的C++程序:

示例

#include <iostream>
#include <string>
using namespace std;

// Function to encrypt a message using Rail Fence Cipher
string encryptMessage(string plaintext, int rails) {
   // Create a matrix to represent the rail fence
   char rail[rails][plaintext.length()];

   // Fill the rail matrix with newline characters
   for (int i = 0; i < rails; i++) {
      for (int j = 0; j < plaintext.length(); j++) {
         rail[i][j] = '\n';
      }
   }

   // Determine the direction of movement
   bool moveDown = false;
   int row = 0, col = 0;

   // Traverse the plaintext and fill the rail matrix
   for (int i = 0; i < plaintext.length(); i++) {
      if (row == 0 || row == rails - 1) {
         moveDown = !moveDown;
      }
      rail[row][col++] = plaintext[i];
      moveDown ? row++ : row--;
   }

   // Construct the cipher text from the rail matrix
   string ciphertext;
   for (int i = 0; i < rails; i++) {
      for (int j = 0; j < plaintext.length(); j++) {
         if (rail[i][j] != '\n') {
            ciphertext.push_back(rail[i][j]);
         }
      }
   }
   return ciphertext;
}

// Function to decrypt the cipher text using Rail Fence Cipher
string decryptMessage(string ciphertext, int rails) {
   char rail[rails][ciphertext.length()];

   // Fill the rail matrix with newline characters
   for (int i = 0; i < rails; i++) {
      for (int j = 0; j < ciphertext.length(); j++) {
         rail[i][j] = '\n';
      }
   }

   // Determine the direction of movement
   bool moveDown = true;
   int row = 0, col = 0;

   // Mark the places with '*'
   for (int i = 0; i < ciphertext.length(); i++) {
      if (row == 0) {
         moveDown = true;
      }
      if (row == rails - 1) {
         moveDown = false;
      }
      rail[row][col++] = '*';
      moveDown ? row++ : row--;
   }

   // Reconstruct the rail matrix with cipher text
   int index = 0;
   for (int i = 0; i < rails; i++) {
      for (int j = 0; j < ciphertext.length(); j++) {
         if (rail[i][j] == '*' && index < ciphertext.length()) {
            rail[i][j] = ciphertext[index++];
         }
      }
   }

   // Construct the plaintext from the rail matrix
   string plaintext;
   row = 0, col = 0;
   for (int i = 0; i < ciphertext.length(); i++) {
      if (row == 0) {
         moveDown = true;
      }
      if (row == rails - 1) {
         moveDown = false;
      }

      if (rail[row][col] != '*') {
         plaintext.push_back(rail[row][col++]);
      }
      moveDown ? row++ : row--;
   }
   return plaintext;
}

int main() {
   cout << "The Encrypted Messages: " << endl;
   cout << encryptMessage("hello Tutorialspoint", 2) << endl;
   cout << encryptMessage("Simple Text", 4) << endl;
   cout << encryptMessage("Cplusplus is great", 5) << endl;

   // Now decryption of the same cipher-text
   cout << "\nThe Decrypted Messages: " << endl;
   cout << decryptMessage("hloTtrasonel uoilpit", 2) << endl;
   cout << decryptMessage("S ieTmletpx", 4) << endl;
   cout << decryptMessage("Csapu etllirupsgs", 5) << endl;

   return 0;
}

以下是上述示例的输出:

输入/输出
The Encrypted Messages: 
hloTtrasonel uoilpit
S ieTmletpx
Csapu etllirupsgs 

The Decrypted Messages: 
hello Tutorialspoint
Simple Text
Cptrgulus lpssiea

复杂性和应用

  • 创建消息所需的行的数量决定了栅栏技术的复杂程度。使用的行数越多,加密就越复杂。此外,如果行数更多,攻击者可能更难以找出消息中字符的初始位置。

  • 然而,即使有多行,栅栏技术仍然不是一种非常安全的加密形式。它始终容易受到某些类型的攻击,攻击者可以快速破解它。

  • 在现代通信中,栅栏技术并不常用。它是各种基本低安全通信协议的组成部分。但是,现在有更安全、更适合保护私人数据的解决方案。

  • 栅栏方法的一个用途是用于儿童的教育游戏或活动。它可以是一种快速而有趣的方法来讲解密码学的 fundamentals。但是,它不应用于任何重要的安全应用。

优点

现在我们了解了栅栏方法背后的基本概念。让我们讨论一下它的优点:

  • 栅栏方法具有许多优点,包括多功能性、简单性和易用性。

  • 栅栏技术相对易于理解和应用,因此在不需要更高安全级别的情况下,它是基本通信的有用选择。栅栏技术可以在无需专用工具或软件的情况下手动执行。

  • 最后,栅栏系统可以使用任意数量的行。它允许用户选择最符合其需求的复杂程度。

缺点

现在让我们讨论栅栏密码的缺点:

  • 该技术的主要缺点是其容易受到攻击、缺乏安全性以及有效性有限。

  • 由于任何具有基本密码学知识的人都可以轻松破解栅栏技术,因此它不是一种安全的加密形式。对于较长的消息,这种方法也不太成功。

  • 此外,某些类型的攻击,例如已知明文攻击,可以针对栅栏方法。因此,攻击者可以简单地发起攻击来解密数据。

限制

使用频率分析,栅栏密码的加密很容易被破解。小于或等于密文长度的数字充当加密密钥。因此它非常容易受到暴力攻击。

广告