- 密碼學教程
- 密碼學 - 首頁
- 密碼學 - 起源
- 密碼學 - 歷史
- 密碼學 - 原理
- 密碼學 - 應用
- 密碼學 - 優點與缺點
- 密碼學 - 現代密碼學
- 密碼學 - 傳統密碼
- 密碼學 - 加密的需求
- 密碼學 - 雙重強度加密
- 密碼系統
- 密碼系統
- 密碼系統 - 組成部分
- 密碼系統攻擊
- 密碼系統 - 彩虹表攻擊
- 密碼系統 - 字典攻擊
- 密碼系統 - 暴力攻擊
- 密碼系統 - 密碼分析技術
- 密碼學型別
- 密碼系統 - 型別
- 公鑰加密
- 現代對稱金鑰加密
- 密碼學雜湊函式
- 金鑰管理
- 密碼系統 - 金鑰生成
- 密碼系統 - 金鑰儲存
- 密碼系統 - 金鑰分發
- 密碼系統 - 金鑰撤銷
- 分組密碼
- 密碼系統 - 流密碼
- 密碼學 - 分組密碼
- 密碼學 - Feistel分組密碼
- 分組密碼的操作模式
- 分組密碼的操作模式
- 電子密碼本 (ECB) 模式
- 密碼分組連結 (CBC) 模式
- 密碼反饋 (CFB) 模式
- 輸出反饋 (OFB) 模式
- 計數器 (CTR) 模式
- 經典密碼
- 密碼學 - 反向密碼
- 密碼學 - 凱撒密碼
- 密碼學 - ROT13 演算法
- 密碼學 - 置換密碼
- 密碼學 - 加密置換密碼
- 密碼學 - 解密置換密碼
- 密碼學 - 乘法密碼
- 密碼學 - 仿射密碼
- 密碼學 - 簡單替換密碼
- 密碼學 - 簡單替換密碼的加密
- 密碼學 - 簡單替換密碼的解密
- 密碼學 - 維吉尼亞密碼
- 密碼學 - 維吉尼亞密碼的實現
- 現代密碼
- Base64 編碼與解碼
- 密碼學 - XOR 加密
- 替換技術
- 密碼學 - 單表代換密碼
- 密碼學 - 單表代換密碼的破解
- 密碼學 - 多表代換密碼
- 密碼學 - Playfair 密碼
- 密碼學 - 希爾密碼
- 多表代換密碼
- 密碼學 - 一次性密碼本密碼
- 一次性密碼本密碼的實現
- 密碼學 - 置換技術
- 密碼學 - 柵欄密碼
- 密碼學 - 列置換密碼
- 密碼學 -隱寫術
- 對稱演算法
- 密碼學 - 資料加密
- 密碼學 - 加密演算法
- 密碼學 - 資料加密標準 (DES)
- 密碼學 - 三重 DES
- 密碼學 - 雙重 DES
- 高階加密標準 (AES)
- 密碼學 - AES 結構
- 密碼學 - AES 變換函式
- 密碼學 - 位元組替換變換
- 密碼學 - 行移位變換
- 密碼學 - 列混淆變換
- 密碼學 - 輪金鑰加變換
- 密碼學 - AES 金鑰擴充套件演算法
- 密碼學 - Blowfish 演算法
- 密碼學 - SHA 演算法
- 密碼學 - RC4 演算法
- 密碼學 - Camellia 加密演算法
- 密碼學 - ChaCha20 加密演算法
- 密碼學 - CAST5 加密演算法
- 密碼學 - SEED 加密演算法
- 密碼學 - SM4 加密演算法
- IDEA - 國際資料加密演算法
- 公鑰(非對稱)密碼演算法
- 密碼學 - RSA 演算法
- 密碼學 - RSA 加密
- 密碼學 - RSA 解密
- 密碼學 - 建立 RSA 金鑰
- 密碼學 - 破解 RSA 密碼
- 密碼學 - ECDSA 演算法
- 密碼學 - DSA 演算法
- 密碼學 - Diffie-Hellman 演算法
- 密碼學中的資料完整性
- 密碼學中的資料完整性
- 訊息認證
- 密碼學數字簽名
- 公鑰基礎設施 (PKI)
- 雜湊
- MD5 (訊息摘要演算法 5)
- SHA-1 (安全雜湊演算法 1)
- SHA-256 (安全雜湊演算法 256 位)
- SHA-512 (安全雜湊演算法 512 位)
- SHA-3 (安全雜湊演算法 3)
- 雜湊密碼
- Bcrypt 雜湊模組
- 現代密碼學
- 量子密碼學
- 後量子密碼學
- 密碼協議
- 密碼學 - SSL/TLS 協議
- 密碼學 - SSH 協議
- 密碼學 - IPsec 協議
- 密碼學 - PGP 協議
- 影像和檔案加密
- 密碼學 - 影像
- 密碼學 - 檔案
- 隱寫術 - 影像
- 檔案加密和解密
- 密碼學 - 檔案加密
- 密碼學 - 檔案解密
- 物聯網中的密碼學
- 物聯網安全挑戰、威脅和攻擊
- 物聯網安全的密碼技術
- 物聯網裝置的通訊協議
- 常用的密碼技術
- 自定義構建密碼演算法(混合密碼學)
- 雲密碼學
- 量子密碼學
- 密碼學中的影像隱寫術
- DNA 密碼學
- 密碼學中的一次性密碼 (OTP) 演算法
- 區別
- 密碼學 - MD5 與 SHA1
- 密碼學 - RSA 與 DSA
- 密碼學 - RSA 與 Diffie-Hellman
- 密碼學與密碼學
- 密碼學 - 密碼學 vs 密碼分析
- 密碼學 - 經典密碼學 vs 量子密碼學
- 密碼學與隱寫術
- 密碼學與加密
- 密碼學與網路安全
- 密碼學 - 流密碼與分組密碼
- 密碼學 - AES 與 DES 密碼
- 密碼學 - 對稱密碼與非對稱密碼
- 密碼學有用資源
- 密碼學 - 快速指南
- 密碼學 - 討論
密碼學 - 希爾密碼
在經典密碼學的語境下,希爾密碼使用多字母替換密碼,這意味著在多個塊級別上進行同質替換。這種多字母替換密碼允許希爾密碼輕鬆地使用二字母組(兩字母塊)、三字母組(三字母塊)或任何其他多尺寸塊來建立統一的密碼。
希爾密碼基於線性代數、高階矩陣(矩陣乘法和矩陣逆)和模算術原理。顯然,它比其他密碼更具有數學性。
希爾密碼也是一種分組密碼。分組密碼使用確定性演算法和對稱金鑰來加密一段文字。與流密碼不同,它不需要一次加密一位。希爾密碼是一種分組密碼,這意味著它可以處理任何大小的塊。
雖然希爾密碼本質上是二字母組的,但它可以擴充套件到任何字母大小的乘法,增加了複雜性和可靠性,從而提高了使用效率。因為希爾密碼的大部分問題和解決方案本質上都是數學性的,所以很容易精確地隱藏字母。
由於希爾密碼相當複雜,讓我們加密文字“CODE”,然後解密生成的密文來學習它的工作原理。為了使示例保持簡單,我們將使用一種簡單的替換方法,其中字母 A 對映到 0,B 對映到 1,依此類推,以符合 2x2 金鑰矩陣。隨著金鑰矩陣大小的增加,希爾密碼變得更加複雜。
歷史
透過使用獨特的方法和技術,密碼學——安全通訊的研究和實踐——防止未經授權的人員或團隊獲取機密資料。保密性、資料完整性、身份驗證等概念在現代密碼學中非常重要。
著名的美國數學家萊斯特·S·希爾於 1929 年開發和改進了希爾密碼技術。希爾密碼使用多種數學技術,這些技術與傳統密碼學中的許多關鍵技術相關。
加密
使用希爾密碼加密取決於以下操作:
E(K, P) = (K*P) mod 26
這裡 K 是我們的金鑰矩陣,P 是向量化的明文。將這兩個項進行矩陣乘法得到加密的密文。讓我們一步一步地開始吧:
選擇一個關鍵字來加密您的明文訊息。讓我們使用隨機關鍵字“DCDF”。使用替換技術,將此項更改為數值 2x2 金鑰矩陣。
然後我們將明文訊息轉換為向量格式。因為我們的金鑰矩陣是 2x2,矩陣乘法需要一個大小為 2x1 的向量。在我們的示例中,我們的訊息有四個字母長,所以我們可以將其分成兩個字母的塊,然後進行替換以獲得我們的明文向量。
最終的密文“WWVA”可以透過將金鑰矩陣與每個 2x1 明文向量進行矩陣相乘,取結果 2x1 向量的模 26,並將結果連線起來生成。所以對於 22 22 21 0 將是 WWVA。
解密
希爾密碼解密過程基於以下操作:
D(K, C) = (K-1 *C) mod 26
這裡 C 是向量化的密文,K 是我們的金鑰矩陣。透過將金鑰矩陣的逆與密文進行矩陣相乘可以得到解密的明文。讓我們使用“WWVA”作為我們的密文一步一步地進行:
我們首先計算金鑰矩陣的逆。為此,我們必須使用模 26 來保持結果在 0 和 25 之間。因此,使用擴充套件歐幾里得方法找到金鑰矩陣行列式的模乘法逆。
之後,我們將密文的 2x1 塊乘以金鑰矩陣的逆,以恢復我們原始的明文訊息“CODE”。
使用 Python 實現
這段 Python 程式碼藉助 NumPy 進行矩陣運算,構建了希爾密碼加密演算法。它建立函式來根據給定的金鑰定義金鑰矩陣,使用生成的金鑰矩陣加密訊息,並進行希爾密碼加密。hill_cipher 函式接受訊息和金鑰作為輸入,建立金鑰矩陣,也使用金鑰矩陣加密訊息,並將輸出列印為密文。
示例
以下是使用 Python 的 numpy 庫實現的希爾密碼的 Python 實現:
import numpy as np
key_matrix = np.zeros((3, 3), dtype=int)
message_vector = np.zeros((3, 1), dtype=int)
cipher_matrix = np.zeros((3, 1), dtype=int)
def get_key_matrix(key):
k = 0
for i in range(3):
for j in range(3):
key_matrix[i][j] = ord(key[k]) % 65
k += 1
def encrypt(message_vector):
for i in range(3):
cipher_matrix[i][0] = 0
for x in range(3):
cipher_matrix[i][0] += (key_matrix[i][x] * message_vector[x][0])
cipher_matrix[i][0] = cipher_matrix[i][0] % 26
def hill_cipher(message, key):
get_key_matrix(key)
for i in range(3):
message_vector[i][0] = ord(message[i]) % 65
encrypt(message_vector)
ciphertext = [chr(cipher_matrix[i][0] + 65) for i in range(3)]
print("The Ciphertext:", "".join(ciphertext))
message = "DOG"
key = "YHGINUKER"
hill_cipher(message, key)
以下是上述示例的輸出:
輸入/輸出
The Ciphertext: YOG
使用 Java 實現
這段 Java 程式碼使用希爾密碼演算法執行加密和解密。加密函式採用明文和金鑰矩陣。返回加密的密文。解密函式採用密文和金鑰矩陣。返回原始明文。行列式計算矩陣的行列式。並計算矩陣的伴隨矩陣(餘因子矩陣)。沿對角線轉換矩陣以轉置矩陣。
示例
請參見以下希爾密碼的 Java 實現程式碼:
import java.util.Arrays;
public class HillCipher {
private static final int MOD = 26;
public static String encryptText(String plaintext, int[][] key) {
plaintext = plaintext.toUpperCase().replaceAll(" ", "");
int n = key.length;
int padding = n - plaintext.length() % n;
if (padding != n) {
plaintext += "X".repeat(padding);
}
StringBuilder ciphertext = new StringBuilder();
for (int i = 0; i < plaintext.length(); i += n) {
int[] block = new int[n];
for (int j = 0; j < n; j++) {
block[j] = plaintext.charAt(i + j) - 'A';
}
int[] encryptedBlock = multiplyMatrix(key, block);
for (int value : encryptedBlock) {
ciphertext.append((char) (value + 'A'));
}
}
return ciphertext.toString();
}
public static String decryptText(String ciphertext, int[][] key) {
int determinant = determinant(key);
int adjoint[][] = adjoint(key);
int n = key.length;
int[][] inverseKey = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
inverseKey[i][j] = (adjoint[i][j] * determinant) % MOD;
if (inverseKey[i][j] < 0) {
inverseKey[i][j] += MOD;
}
}
}
return encryptText(ciphertext, inverseKey);
}
private static int[] multiplyMatrix(int[][] key, int[] block) {
int n = key.length;
int[] result = new int[n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
result[i] += key[i][j] * block[j];
}
result[i] %= MOD;
}
return result;
}
private static int determinant(int[][] matrix) {
if (matrix.length == 1) {
return matrix[0][0];
}
int det = 0;
for (int i = 0; i < matrix.length; i++) {
int[][] minor = new int[matrix.length - 1][matrix.length - 1];
for (int j = 1; j < matrix.length; j++) {
for (int k = 0, col = 0; k < matrix.length; k++) {
if (k == i) continue;
minor[j - 1][col++] = matrix[j][k];
}
}
det += Math.pow(-1, i) * matrix[0][i] * determinant(minor);
}
return det;
}
private static int[][] adjoint(int[][] matrix) {
int n = matrix.length;
int[][] adjoint = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int[][] minor = new int[n - 1][n - 1];
for (int k = 0, row = 0; k < n; k++) {
if (k == i) continue;
for (int l = 0, col = 0; l < n; l++) {
if (l == j) continue;
minor[row][col++] = matrix[k][l];
}
row++;
}
adjoint[i][j] = (int) Math.pow(-1, i + j) * determinant(minor);
}
}
return transpose(adjoint);
}
private static int[][] transpose(int[][] matrix) {
int[][] result = new int[matrix.length][matrix.length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
result[i][j] = matrix[j][i];
}
}
return result;
}
public static void main(String[] args) {
int[][] key = {{6, 24, 1}, {13, 16, 10}, {20, 17, 15}};
String plaintext = "POINT";
String ciphertext = encryptText(plaintext, key);
System.out.println("The Encrypted Text: " + ciphertext);
String decrypted = decryptText(ciphertext, key);
System.out.println("The Decrypted Text: " + decrypted);
}
}
以下是上述示例的輸出:
輸入/輸出
The Encrypted Text: SFILBS The Decrypted Text: POINTX
使用 C++ 實現
這段 C++ 程式碼實現了希爾密碼的加密和解密演算法。multiplyMatrix 函式將執行矩陣乘法。之後,determinant 函式將計算矩陣的行列式。然後,adjoint 函式計算矩陣的伴隨矩陣。encrypt 函式使用金鑰矩陣加密明文。decrypt 函式使用金鑰矩陣解密密文。
示例
請參見下面的 Hill 密碼 C++ 實現程式碼:
#include <iostream>
#include <vector>
using namespace std;
const int MOD = 26;
vector<vector<int>> multiplyMatrix(const vector<vector<int>>& key, const vector<int>& block) {
int n = key.size();
vector<vector<int>> result(n, vector<int>(1, 0));
for (int i = 0; i < n; i++) {
for (int j = 0; j < 1; j++) {
for (int k = 0; k < n; k++) {
result[i][j] += key[i][k] * block[k];
}
result[i][j] %= MOD;
}
}
return result;
}
int determinant(const vector<vector<int>>& matrix) {
if (matrix.size() == 1) {
return matrix[0][0];
}
int det = 0;
int sign = 1;
for (int i = 0; i < matrix.size(); i++) {
vector<vector<int>> minor(matrix.size() - 1, vector<int>(matrix.size() - 1, 0));
for (int j = 1; j < matrix.size(); j++) {
for (int k = 0, col = 0; k < matrix.size(); k++) {
if (k == i) continue;
minor[j - 1][col++] = matrix[j][k];
}
}
det += sign * matrix[0][i] * determinant(minor);
sign *= -1;
}
return det;
}
vector<vector<int>> adjoint(const vector<vector<int>>& matrix) {
int n = matrix.size();
vector<vector<int>> adjoint(n, vector<int>(n, 0));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
vector<vector<int>> minor(n - 1, vector<int>(n - 1, 0));
for (int k = 0, row = 0; k < n; k++) {
if (k == i) continue;
for (int l = 0, col = 0; l < n; l++) {
if (l == j) continue;
minor[row][col++] = matrix[k][l];
}
row++;
}
adjoint[i][j] = determinant(minor) * ((i + j) % 2 == 0 ? 1 : -1);
}
}
vector<vector<int>> result = adjoint;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
swap(result[i][j], result[j][i]);
}
}
return result;
}
string encrypt(const string& plaintext, const vector<vector<int>>& key) {
string modifiedPlaintext = plaintext;
int n = key.size();
int padding = n - modifiedPlaintext.size() % n;
if (padding != n) {
modifiedPlaintext += string(padding, 'X');
}
string ciphertext = "";
for (int i = 0; i < modifiedPlaintext.size(); i += n) {
vector<int> block(n, 0);
for (int j = 0; j < n; j++) {
block[j] = modifiedPlaintext[i + j] - 'A';
}
vector<vector<int>> encryptedBlock = multiplyMatrix(key, block);
for (const auto& row : encryptedBlock) {
for (int value : row) {
ciphertext += (char) (value + 'A');
}
}
}
return ciphertext;
}
string decrypt(const string& ciphertext, const vector<vector<int>>& key) {
int det = determinant(key);
vector<vector<int>> adj = adjoint(key);
vector<vector<int>> inverseKey = key;
int n = key.size();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
inverseKey[i][j] = (adj[i][j] * det) % MOD;
if (inverseKey[i][j] < 0) {
inverseKey[i][j] += MOD;
}
}
}
return encrypt(ciphertext, inverseKey);
}
int main() {
vector<vector<int>> key = {{6, 24, 1}, {13, 16, 10}, {20, 17, 15}};
string plaintext = "HELLO";
string ciphertext = encrypt(plaintext, key);
cout << "The Encrypted Text: " << ciphertext << endl;
string decrypted = decrypt(ciphertext, key);
cout << "The Decrypted Text: " << decrypted << endl;
return 0;
}
以下是上述示例的輸出:
輸入/輸出
The Encrypted Text: TFJJZX The Decrypted Text: HELLOX
優勢
Hill 密碼加密演算法具有以下優勢:
安全性 − Hill 密碼使用字母塊而不是單個字母進行運算,因此比其他傳統的替換密碼更安全。它不易受到使用頻率分析的攻擊。
靈活性 − Hill 密碼可以加密和解密包含大寫字母、小寫字母、標點符號和空格的訊息。由於其適應性強,它可以用於加密各種文字檔案。
數學背景 − Hill 密碼基於線性代數的思想,為理解和建立高階加密方法提供了框架。它提供了一個研究加密技術和矩陣之間關係的機會。
金鑰強度 − 加密金鑰矩陣的大小和不可預測性直接影響 Hill 密碼的安全性。透過使用更大的金鑰矩陣可以提高加密強度,這將使未經授權的方更難以解密訊息。
複雜性 − Hill 密碼在沒有加密金鑰的情況下更難理解,因為它在加密過程中使用了矩陣運算。這進一步提高了演算法的安全性。
Hill 密碼的安全性
當使用 2x2 矩陣時,Hill 密碼很容易破解。然而,對於提供 256 種可能數字的現代加密系統而言,Hill 密碼效率非常低。
先前已經證明,Hill 密碼的線性相關性在防禦已知明文攻擊方面存在已知的漏洞。由於 Hill 密碼僅使用常規的代數方法求解,因此任何具有線性密文對的系統都可以輕鬆破解 Hill 密碼矩陣。
然而,增加矩陣乘法的次數並不能顯著增強系統安全性。另一方面,它可以與非線性過程結合使用以支援擴散。像 AES 這樣的現代高階加密技術使用不同的擴散來更好地增強系統安全性。
Lester S. Hill 開發了一種用於 6x6 矩陣密碼的專用機器,該機器被證明安全性有所提高。但由於其主要設定不可調整,其實際應用受到限制。