密碼學 - 位元組替換變換



高階加密標準 (AES) 是一種流行的對稱加密技術的關鍵組成部分,其中一個關鍵組成部分是位元組替換變換。AES 使用通常大小為 128 位(16 位元組)的資料塊。它以輪次工作,每一輪都涉及對資料進行多次修改以確保加密資料的安全性。除了第一輪之外,在所有後續輪次中都使用位元組替換變換。

位元組替換變換(也稱為“SubBytes”或“S-Box”操作)是一種非線性替換操作,它將輸入資料中的每個位元組替換為來自固定替換表的相應位元組,該替換表稱為“S-Box”。S-Box 是一個預先建立的常量表,包含 256 個條目,每個條目都是 8 位長。由於其精心設計,S-Box 透過引入非線性性和混淆來防止各種密碼攻擊,包括差分和線性密碼分析。

它是如何工作的?

  • 輸入 - 資料輸入是一個 4x4 矩陣(16 位元組)。SubBytes 操作應用於矩陣中的每個位元組。
  • 替換 - 使用來自 S-Box 的位元組替換矩陣中的每個位元組。逐位元組進行替換,使用 S-Box 查詢匹配的替換位元組。
  • 輸出 - 4x4 矩陣發生變化,每個位元組都被換成其對應的 S-Box 值。

AES 演算法的固定、眾所周知的 S-Box 函式模糊了輸入和輸出之間的關係,使攻擊者更難以推斷出關於加密資料的模式或細節。

位元組替換變換有助於獲得健壯加密系統所需的擴散和混淆特性。擴散確保明文的一個區域中的變化會影響密文的大部分,而混淆確保金鑰和密文之間的關係複雜且難以分析。

AES 中的位元組替換變換是一個關鍵元件,它透過將 S-Box 中的值替換為每個資料位元組來增強加密並新增非線性,從而提高加密過程的安全性並抵抗密碼攻擊。

替換盒 (S-Box)

“替換盒”或簡稱 S-Box 是幾種密碼方法(包括分組密碼、對稱金鑰加密和高階加密標準 (AES))的重要特徵。S-Box 是一個固定的替換表,用於將輸入值(通常是二進位制數字或位元組)替換為輸出值。它充當非線性變換,透過在加密過程中新增混淆和複雜性來增強密碼演算法的安全性。

特徵

S-Box 的重要特徵包括 -

  • 非線性 - S-Box 被設計為非線性的,因為輸入和輸出值之間的關係不是簡單的數學函式。此係統的非線性有助於防止多種密碼攻擊,包括非對稱和線性密碼分析。
  • 混淆 - S-Box 對於實現加密的混淆特性是必要的。它們確保密文和明文之間存在複雜的關係,這使得攻擊者難以確定關於加密資料的模式和細節。
  • 固定且預定義 - 密碼演算法的 S-Box 是一個固定且眾所周知的元件。其公開性和標準設計確保了加密過程的透明度和信心。
  • 替換 - S-Box 執行替換過程,將 S-Box 中的相應輸出值替換為每個輸入值。這種替換逐位或逐位元組進行,具體取決於演算法的構造方式。

在 AES 的上下文中,S-Box 是在每個加密輪次中用於位元組替換變換的特定替換表。AES S-Box 是 AES 演算法安全性的一個關鍵因素,因為它旨在抵禦各種密碼攻擊。總而言之,S-Box 是一個固定且預定義的替換表,透過複雜且非線性地將輸入值替換為相應的輸出值,從而向密碼方法新增非線性並提高安全性。

使用 Python 實現

此程式碼使用 AES S-box 實現位元組替換變換。它將 4x4 位元組矩陣作為輸入,將 S-box 應用於每個位元組,然後生成一個包含替換位元組的新矩陣。

示例

# S-box substitution table for Advance Encryption Standard
S_BOX = (
   0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
)

def sbt(input_matrix):

   # Substitute bytes in the input matrix using the AES S-box.
   output_matrix = []
   for row in input_matrix:
      new_row = []
      for byte in row:
         new_row.append(S_BOX[byte])
      output_matrix.append(new_row)
   return output_matrix

# function execution
input_matrix = [
   [0x32, 0x88, 0x31, 0xe0],
   [0x43, 0x5a, 0x31, 0x37],
   [0xf6, 0x30, 0x98, 0x07],
   [0xa8, 0x8d, 0xa2, 0x34]
]

output_matrix = sbt(input_matrix)
print("Our Input Matrix:")
for row in input_matrix:
   print(row)
print("\nOur Output Matrix (After Substitution):")
for row in output_matrix:
   print(row)

以下是上述示例的輸出 -

輸入/輸出

Our Input Matrix:
[50, 136, 49, 224]
[67, 90, 49, 55]
[246, 48, 152, 7]
[168, 141, 162, 52]

Our Output Matrix (After Substitution):
[35, 196, 199, 225]
[26, 190, 199, 154]
[66, 4, 70, 197]
[194, 93, 58, 24]

使用 Java 實現

現在我們將使用 Java 實現位元組替換變換的程式碼。此 Java 程式碼使用 AES S-box 實現位元組替換變換。它將 4x4 位元組矩陣作為輸入,將 S-box 應用於每個位元組,然後生成一個包含替換位元組的新矩陣。main 方法展示瞭如何使用此函式以及示例輸入矩陣。以下是位元組替換變換的實現 -

示例

public class SBT {

   // S-box substitution table for Advance Encryption Standard
   private static final int[] S_BOX = {
      0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
      0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
      0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
      0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
      0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
      0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
      0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
      0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
      0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
      0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
      0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
      0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
      0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
      0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
      0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
      0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
   };

   public static void main(String[] args) {
      int[][] inputMatrix = {
         {0x32, 0x88, 0x31, 0xe0},
         {0x43, 0x5a, 0x31, 0x37},
         {0xf6, 0x30, 0x98, 0x07},
         {0xa8, 0x8d, 0xa2, 0x34}
      };

      int[][] outputMatrix = SBT(inputMatrix);
      System.out.println("Our Input Matrix:");
      ourMatrix(inputMatrix);
      System.out.println("\nOur Output Matrix (After Substitution):");
      ourMatrix(outputMatrix);
   }

   public static int[][] SBT(int[][] inputMatrix) {
      int[][] outputMatrix = new int[4][4];
      for (int i = 0; i < 4; i++) {
         for (int j = 0; j < 4; j++) {
            outputMatrix[i][j] = S_BOX[inputMatrix[i][j]];
         }
      }
      return outputMatrix;
   }

   private static void ourMatrix(int[][] matrix) {
      for (int i = 0; i < matrix.length; i++) {
         System.out.print("[");
         for (int j = 0; j < matrix[i].length; j++) {
            System.out.printf("%d", matrix[i][j]);
            if (j < matrix[i].length - 1) {
               System.out.print(", ");
            }
         }
         System.out.println("]");
      }
   }
}

以下是上述示例的輸出 -

輸入/輸出

Our Input Matrix:
[50, 136, 49, 224]
[67, 90, 49, 55]
[246, 48, 152, 7]
[168, 141, 162, 52]

Our Output Matrix (After Substitution):
[35, 196, 199, 225]
[26, 190, 199, 154]
[66, 4, 70, 197]
[194, 93, 58, 24]

使用 C++ 實現

此 C++ 程式碼實現了先前提供的 Java 程式碼的功能。輸入和輸出矩陣以適當的格式生成,並且替換是透過名為 substituteBytes 的函式的定義使用 AES S-box 完成的。因此,程式碼如下 -

示例

#include <iostream>
#include <iomanip>

// S-box substitution table for Advance Encryption Stadard
const unsigned char S_BOX[] = {
   0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

void sbt(unsigned char inputMatrix[4][4], unsigned char outputMatrix[4][4]) {
   for (int i = 0; i < 4; i++) {
      for (int j = 0; j < 4; j++) {
         outputMatrix[i][j] = S_BOX[inputMatrix[i][j]];
      }
   }
}

void ourMatrix(unsigned char matrix[4][4]) {
   std::cout << "Our Input Matrix:" << std::endl;
   for (int i = 0; i < 4; i++) {
      std::cout << "[";
      for (int j = 0; j < 4; j++) {
         std::cout << std::setw(3) << (int)matrix[i][j];
         if (j < 3) {
            std::cout << ", ";
         }
      }
      std::cout << "]" << std::endl;
   }
}

void ourMatrixHex(unsigned char matrix[4][4]) {
   std::cout << "\nOur Output Matrix (After Substitution):" << std::endl;
   for (int i = 0; i < 4; i++) {
      std::cout << "[";
      for (int j = 0; j < 4; j++) {
         std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)matrix[i][j];
         if (j < 3) {
            std::cout << ", ";
         }
      }
      std::cout << "]" << std::endl;
   }
}

int main() {
   unsigned char inputMatrix[4][4] = {
      {0x32, 0x88, 0x31, 0xe0},
      {0x43, 0x5a, 0x31, 0x37},
      {0xf6, 0x30, 0x98, 0x07},
      {0xa8, 0x8d, 0xa2, 0x34}
   };

   unsigned char outputMatrix[4][4];
   sbt(inputMatrix, outputMatrix);
   ourMatrix(inputMatrix);
   ourMatrixHex(outputMatrix);

   return 0;
}

輸出M

Our Input Matrix:
[ 50, 136,  49, 224]
[ 67,  90,  49,  55]
[246,  48, 152,   7]
[168, 141, 162,  52]

Our Output Matrix (After Substitution):
[23, c4, c7, e1]
[1a, be, c7, 9a]
[42, 04, 46, c5]
[c2, 5d, 3a, 18]

總結

替代位元組變換透過引入非線性與混淆增強了AES加密,這是健壯的密碼系統所需的兩個特性。它增強了AES演算法針對不同密碼攻擊的總體防護能力,並提高了安全性。

廣告

© . All rights reserved.