3253 字
16 分鐘
🔐 密碼學基礎知識總結
2025-08-04
正在播放 I Really Want To Stay At Your House
Cover image for 🔐 密碼學基礎知識總結

#📚 內容目錄

#基礎編碼篇

#現代密碼篇

#實戰技術篇


#一、Base編碼

Base編碼是一種將二進制數據轉換為文本的編碼方式,廣泛應用於CTF競賽和實際數據傳輸中。

#1. Base系列特征

編碼類型字符集特征填充字符應用場景
Base160-9, A-F密文長度為偶數十六進制表示
Base32A-Z, 2-7包含數字2-7=DNS編碼
Base64A-Z, a-z, 0-9, +, /密文長度為4的倍數=郵件、URL編碼
Base58A-Z, a-z, 0-9 (去除0,O,I,l)無混淆字符Bitcoin地址
Base85ASCII 33-117高效編碼PDF、Git
Base91A-Z, a-z, 0-9, !#$%&()*+,./:;<=>?@[]^_`{}~-高密度編碼
Base100Emoji表情符號表情符號組成隱寫術

#2. 識別技巧

def identify_base_encoding(text):
"""
根據字符特征識別Base編碼類型
"""
if all(c in '0123456789ABCDEF' for c in text.upper()):
return "可能是Base16 (Hex)"
if all(c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=' for c in text.upper()):
return "可能是Base32"
if all(c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' for c in text):
return "可能是Base64"
# 檢查是否包含emoji
if any(ord(c) > 127 for c in text):
return "可能是Base100或其他Unicode編碼"
return "未知編碼"

#3. CTF常見題型

疊套加密(多層編碼)

import base64
# 示例:三層Base64編碼
def multi_base64_decode(text, layers=3):
result = text
for i in range(layers):
try:
result = base64.b64decode(result).decode('utf-8')
print(f"第{i+1}層解碼結果: {result}")
except:
print(f"第{i+1}層解碼失敗")
break
return result

換表加密(自定義字符映射)

# 換表解密示例
def custom_base64_decode(cipher, custom_table):
standard_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
# 構建轉換字典
trans = str.maketrans(custom_table, standard_table)
standard_cipher = cipher.translate(trans)
return base64.b64decode(standard_cipher)
# 實際案例
custom_table = "J K L M N O x y U V z A B C D E F G H 7 8 9 P Q I a b c d e f g h i j k l m W X Y Z 0 1 2 3 4 5 6 R S T n o p q r s t u v w + / ="
cipher = "FlZNfnF6Qol6e9w17WwQQoGYBQCgIkGTa9w3IQKw"
print(custom_base64_decode(cipher, custom_table))

異或編碼組合

def base64_xor_decode(cipher, key):
# 先Base64解碼
decoded = base64.b64decode(cipher)
# 再進行XOR運算
result = bytes([decoded[i] ^ ord(key[i % len(key)]) for i in range(len(decoded))])
return result.decode('utf-8')

#二、古典密碼

#1. 替換密碼

  • 凱撒密碼:位移變換

    # 凱撒解密腳本
    def caesar_decrypt(cipher, shift):
    return ''.join([chr((ord(c)-ord('A')-shift)%26+ord('A')) if c.isupper()
    else chr((ord(c)-ord('a')-shift)%26+ord('a')) for c in cipher])
  • 埃特巴什碼:字母表鏡像映射(A↔Z, B↔Y…)

  • 簡單替換:隨機字母映射(需詞頻分析破解)

#2. 移位密碼

  • 柵欄密碼

    明文: THEQUICKBROWNFOX
    2欄柵欄:
    T E U C B O N F X
    H Q I K R W O
    密文: TEUCBOFNXHQIKRWO
  • Playfair密碼:5×5矩陣雙字母加密

  • 維吉尼亞密碼:多表替換(需卡西斯基試驗破譯)

#3. 特殊編碼

  • 社會主義核心價值觀編碼:中文詞語映射
  • 豬圈密碼:符號替代

#三、近代密碼

#1. Enigma機

  • 德國二戰加密設備,通過轉子機械實現多表替換

#四、現代密碼學

#1. 對稱密碼(Symmetric Cryptography)

對稱加密使用相同的密鑰進行加密和解密,速度快但密鑰分發困難。

#分組密碼(Block Cipher)

算法密鑰長度分組大小工作模式安全狀態
DES56位64位ECB/CBC/CFB/OFB❌ 已破解
3DES112/168位64位同DES⚠️ 逐步淘汰
AES128/192/256位128位ECB/CBC/GCM/CTR✅ 安全
Blowfish32-448位64位各種模式✅ 安全
Twofish128/192/256位128位各種模式✅ 安全

AES加密模式詳解

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
# ECB模式 - 不推薦使用
def aes_ecb_encrypt(plaintext, key):
cipher = AES.new(key, AES.MODE_ECB)
padded_text = pad(plaintext.encode(), AES.block_size)
return cipher.encrypt(padded_text)
# CBC模式 - 推薦使用
def aes_cbc_encrypt(plaintext, key):
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_text = pad(plaintext.encode(), AES.block_size)
ciphertext = cipher.encrypt(padded_text)
return iv + ciphertext # IV需要傳輸
# GCM模式 - 提供認證
def aes_gcm_encrypt(plaintext, key):
nonce = get_random_bytes(12)
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
ciphertext, tag = cipher.encrypt_and_digest(plaintext.encode())
return nonce + tag + ciphertext

#流密碼(Stream Cipher)

算法密鑰長度特點應用場景
RC440-2048位快速但存在弱點❌ 已廢棄
ChaCha20256位現代流密碼,高安全性TLS、VPN
Salsa20256位ChaCha20的前身學術研究
from Crypto.Cipher import ChaCha20
def chacha20_encrypt(plaintext, key):
nonce = get_random_bytes(12)
cipher = ChaCha20.new(key=key, nonce=nonce)
ciphertext = cipher.encrypt(plaintext.encode())
return nonce + ciphertext

#2. 非對稱密碼(Asymmetric Cryptography)

非對稱加密使用不同的密鑰進行加密和解密,解決了密鑰分發問題。

#RSA算法

數學基礎:基於大整數分解的困難性

  • 密鑰生成

    • 選擇兩個大質數 p, q
    • 計算 n = p × q, φ(n) = (p-1)(q-1)
    • 選擇 e 使得 gcd(e,φ(n)) = 1
    • 計算 d 滿足 ed ≡ 1 (mod φ(n))
    • 公鑰:(n, e),私鑰:(n, d)
  • 加密/解密

    • 加密:c ≡ m^e (mod n)
    • 解密:m ≡ c^d (mod n)
# RSA完整實現示例
from Crypto.Util.number import long_to_bytes, bytes_to_long, isPrime, getRandomNBitInteger
def generate_rsa_keypair(bits=2048):
"""生成RSA密鑰對"""
while True:
p = getRandomNBitInteger(bits // 2)
if isPrime(p):
break
while True:
q = getRandomNBitInteger(bits // 2)
if isPrime(q) and q != p:
break
n = p * q
phi = (p - 1) * (q - 1)
e = 65537 # 常用的公鑰指數
d = pow(e, -1, phi)
return {
'public': (n, e),
'private': (n, d),
'primes': (p, q)
}
def rsa_encrypt(message, public_key):
"""RSA加密"""
n, e = public_key
m = bytes_to_long(message.encode())
c = pow(m, e, n)
return c
def rsa_decrypt(ciphertext, private_key):
"""RSA解密"""
n, d = private_key
m = pow(ciphertext, d, n)
return long_to_bytes(m).decode()
# CTF中的RSA解密示例
def ctf_rsa_decrypt():
p = 152276107194759839394339252953668929833379494272797635215678777394989176086311370136035478447887926444275784082066390686965320698243113804043171803008108957334907494436138284735908220245791716231134027668300903468613086977898318244422816904811663818867009341751581380232066351461067404386138711392602905182327
q = 165862216368738151171691047077971125385823304861583668749112440485286071513555171553668744837558717911342949436706045003893101207778257828156155579957939073590381726467515305197248665285721804095245979532718423232742857246879254699058634781094524194465195004455721760308439281036465034307352501227102299122599
e = 65537
c = 8714149934588122613890609205826559063957396235456334581066750104141833387128819259074228632737215784067681665337373847122241506740977460425676706234123688048971299968252735566083061567386357327514300746902937654004543191945690400727133317228366779579116882233771039719002815276546167694160681831378762223177951840415429867605824997691072569915435484862548063841182891523397571914055707256503122950455644515402154037908557382756498138387988939464887512595990270123841900640997837144301259531459279512993819808359480410211723491073722980281648910041025010174785548169983002872841283535091066006242941399443173584257860
n = p * q
phi = (p-1) * (q-1)
d = pow(e, -1, phi)
plaintext = pow(c, d, n)
return long_to_bytes(plaintext)

#橢圓曲線密碼學(ECC)

數學基礎:基於橢圓曲線離散對數問題

# ECC點運算示例
class ECCPoint:
def __init__(self, x, y, curve):
self.x = x
self.y = y
self.curve = curve
def __add__(self, other):
"""橢圓曲線點加法"""
if self.x == other.x:
if self.y == other.y:
# 點倍乘
s = (3 * self.x * self.x + self.curve.a) * pow(2 * self.y, -1, self.curve.p)
else:
# 逆元,返回無窮遠點
return None
else:
s = (other.y - self.y) * pow(other.x - self.x, -1, self.curve.p)
x3 = (s * s - self.x - other.x) % self.curve.p
y3 = (s * (self.x - x3) - self.y) % self.curve.p
return ECCPoint(x3, y3, self.curve)
算法密鑰長度安全強度等效RSA特點
ECC-256256位RSA-3072密鑰短,速度快
ECC-384384位RSA-7680高安全性
ECC-521521位RSA-15360最高安全級別

#3. 哈希函數(Hash Functions)

哈希函數將任意長度的輸入映射為固定長度的輸出,具有單向性、抗碰撞性等特性。

算法輸出長度內部狀態安全性應用場景
MD5128位128位❌ 已破解文件校驗(不推薦)
SHA-1160位160位⚠️ 逐步淘汰Git(逐漸替換)
SHA-256256位256位✅ 安全Bitcoin、證書
SHA-3可變1600位✅ 安全新一代標準
Blake2b可變512位✅ 安全高性能場景
RIPEMD-160160位160位✅ 安全Bitcoin地址生成
import hashlib
import hmac
# 常用哈希函數示例
def hash_examples():
message = b"Hello, Cryptography!"
# MD5(不安全,僅作演示)
md5_hash = hashlib.md5(message).hexdigest()
print(f"MD5: {md5_hash}")
# SHA-256(推薦)
sha256_hash = hashlib.sha256(message).hexdigest()
print(f"SHA-256: {sha256_hash}")
# SHA-3(新標準)
sha3_hash = hashlib.sha3_256(message).hexdigest()
print(f"SHA3-256: {sha3_hash}")
# HMAC(帶密鑰的哈希)
key = b"secret_key"
hmac_hash = hmac.new(key, message, hashlib.sha256).hexdigest()
print(f"HMAC-SHA256: {hmac_hash}")
# 哈希長度擴展攻擊示例
def length_extension_attack():
"""演示SHA-1/SHA-256的長度擴展攻擊"""
# 已知:hash(secret || known_message) = known_hash
# 目標:計算hash(secret || known_message || padding || attack_message)
from hashlib import sha256
import struct
def sha256_padding(msg_len):
"""計算SHA-256的填充"""
msg_bit_len = msg_len * 8
padding = b'\x80'
# 填充到448 mod 512
while (len(padding) + msg_len) % 64 != 56:
padding += b'\x00'
# 添加長度(8字節大端序)
padding += struct.pack('>Q', msg_bit_len)
return padding
# 這只是演示概念,實際攻擊需要更復雜的實現
print("長度擴展攻擊需要已知消息長度和哈希值")

#七、數字簽名(Digital Signatures)

數字簽名提供身份認證、完整性保護和不可否認性。

#RSA簽名

from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
def rsa_sign_verify():
# 生成密鑰對
key = RSA.generate(2048)
private_key = key
public_key = key.publickey()
# 要簽名的消息
message = b"Important document"
# 創建簽名
hash_obj = SHA256.new(message)
signer = PKCS1_v1_5.new(private_key)
signature = signer.sign(hash_obj)
# 驗證簽名
verifier = PKCS1_v1_5.new(public_key)
try:
verifier.verify(hash_obj, signature)
print("簽名驗證成功")
except ValueError:
print("簽名驗證失敗")

#ECDSA簽名

from ecdsa import SigningKey, VerifyingKey, SECP256k1
import hashlib
def ecdsa_sign_verify():
# 生成密鑰對
private_key = SigningKey.generate(curve=SECP256k1)
public_key = private_key.get_verifying_key()
# 簽名
message = b"Blockchain transaction"
signature = private_key.sign(message, hashfunc=hashlib.sha256)
# 驗證
try:
public_key.verify(signature, message, hashfunc=hashlib.sha256)
print("ECDSA簽名驗證成功")
except:
print("ECDSA簽名驗證失敗")

#八、攻擊技術

#1. 密碼分析(Cryptanalysis)

#對稱密碼攻擊

  • 差分分析:分析明文差異對密文的影響(針對DES)
  • 線性分析:利用線性逼近攻擊(針對AES)
  • 積分攻擊:針對AES的高級攻擊方法
  • 中間相遇攻擊:針對多輪加密的攻擊

#非對稱密碼攻擊

# RSA攻擊示例集合
def rsa_attacks():
"""常見RSA攻擊方法"""
# 1. 小指數攻擊(e=3時)
def small_exponent_attack(c, n, e=3):
import gmpy2
if e == 3:
# 如果c < n,則m^3 = c
m = gmpy2.iroot(c, 3)[0]
return m
# 2. 共模攻擊(相同n,不同e)
def common_modulus_attack(c1, c2, e1, e2, n):
import gmpy2
# 擴展歐幾里得算法求s1, s2使得s1*e1 + s2*e2 = 1
def extended_gcd(a, b):
if a == 0:
return b, 0, 1
gcd, x1, y1 = extended_gcd(b % a, a)
x = y1 - (b // a) * x1
y = x1
return gcd, x, y
gcd, s1, s2 = extended_gcd(e1, e2)
if gcd == 1:
m = pow(c1, s1, n) * pow(c2, s2, n) % n
return m
# 3. 威納攻擊(d較小時)
def wiener_attack(e, n):
# 使用連分數分解e/n
# 這裡簡化演示概念
print("威納攻擊適用於d < n^0.25的情況")
# 模數分解攻擊
def factorization_attacks():
"""RSA模數分解方法"""
# Pollard's rho算法
def pollards_rho(n):
import math
if n % 2 == 0:
return 2
x = 2
y = 2
d = 1
def f(x):
return (x * x + 1) % n
while d == 1:
x = f(x)
y = f(f(y))
d = math.gcd(abs(x - y), n)
return d if d != n else None

#2. 側信道攻擊(Side-Channel Attacks)

# 計時攻擊演示
import time
import statistics
def timing_attack_demo():
"""演示計時攻擊的概念"""
def vulnerable_compare(guess, target):
"""有漏洞的字符串比較"""
for i in range(min(len(guess), len(target))):
if guess[i] != target[i]:
return False
time.sleep(0.001) # 模擬處理時間
return len(guess) == len(target)
def timing_attack(target_length):
"""通過計時攻擊猜測密碼"""
charset = 'abcdefghijklmnopqrstuvwxyz0123456789'
result = ""
for pos in range(target_length):
best_char = ''
max_time = 0
for char in charset:
guess = result + char + 'a' * (target_length - pos - 1)
# 測量多次取平均值
times = []
for _ in range(10):
start = time.time()
vulnerable_compare(guess, "secret123") # 假設目標
times.append(time.time() - start)
avg_time = statistics.mean(times)
if avg_time > max_time:
max_time = avg_time
best_char = char
result += best_char
print(f"當前猜測: {result}")
return result

#3. 社會工程攻擊

  • 密碼字典攻擊:使用常見密碼列表
  • 彩虹表攻擊:預計算哈希表
  • 鍵盤模式攻擊:基於鍵盤布局的密碼

#九、CTF解題技巧

#1. 題型識別

def crypto_challenge_identifier(ciphertext):
"""CTF密碼學題型識別工具"""
# 統計字符頻率
char_freq = {}
for c in ciphertext:
char_freq[c] = char_freq.get(c, 0) + 1
# 分析長度特征
length = len(ciphertext)
# 判斷可能的編碼類型
if all(c in '01' for c in ciphertext):
return "二進制編碼"
if all(c in '0123456789ABCDEF' for c in ciphertext.upper()):
return "十六進制編碼"
if length % 4 == 0 and all(c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' for c in ciphertext):
return "Base64編碼"
# 頻率分析
most_common = max(char_freq.values())
if most_common / length > 0.12: # 英語中E的頻率約12%
return "可能是單表替換密碼"
return "複雜密碼或多重編碼"
# 自動化解題腳本
def auto_decode_pipeline(ciphertext):
"""自動化解碼流水線"""
import base64
results = []
# 嘗試Base64
try:
decoded = base64.b64decode(ciphertext).decode('utf-8')
results.append(f"Base64: {decoded}")
except:
pass
# 嘗試十六進制
try:
decoded = bytes.fromhex(ciphertext).decode('utf-8')
results.append(f"Hex: {decoded}")
except:
pass
# 嘗試凱撒密碼(所有可能的偏移)
for shift in range(26):
decoded = ''.join([chr((ord(c) - ord('A') - shift) % 26 + ord('A')) if c.isupper()
else chr((ord(c) - ord('a') - shift) % 26 + ord('a')) if c.islower()
else c for c in ciphertext])
if 'flag' in decoded.lower() or 'ctf' in decoded.lower():
results.append(f"Caesar {shift}: {decoded}")
return results

#2. 常見出題套路

  1. 多層編碼:Base64 → Hex → Caesar
  2. 異或運算:flag ⊕ key = cipher
  3. RSA變形:小指數、共模攻擊、威納攻擊
  4. 古典密碼:維吉尼亞、Playfair、柵欄密碼
  5. 現代密碼:AES-ECB模式、CBC字節翻轉攻擊

#十、工具與資源

#1. 在線工具

工具名稱功能網址
CyberChef萬能編解碼工具https://gchq.github.io/CyberChef/
dCode古典密碼分析https://www.dcode.fr/
CMD5MD5哈希查詢https://www.cmd5.com/
FactorDB大數分解查詢http://factordb.com/
QuipQuip替換密碼求解https://quipqiup.com/

#2. 本地工具

Terminal window
# 密碼破解工具
sudo apt install hashcat john
# 密碼學庫
pip install pycryptodome gmpy2 sympy
# CTF專用工具
git clone https://github.com/Ganapati/RsaCtfTool.git
git clone https://github.com/hellman/xortool.git

#3. Python密碼學庫

# 推薦的Python密碼學庫
libraries = {
'pycryptodome': '現代密碼學實現',
'cryptography': '高級密碼學API',
'hashlib': '哈希函數(內建)',
'gmpy2': '大數運算',
'sympy': '數學計算',
'ecdsa': '橢圓曲線數字簽名',
'sage': '數學計算框架(CTF神器)'
}

#4. 學習資源

  • 書籍推薦

    • 《應用密碼學》- Bruce Schneier
    • 《現代密碼學教程》- Jonathan Katz
    • 《密碼編碼學與網絡安全》- William Stallings
  • 在線課程

    • Coursera: Cryptography I (Stanford)
    • edX: Introduction to Cryptography
  • CTF平台


#結語

密碼學是一個不斷發展的領域,從古典的手工密碼到現代的量子密碼學,技術在不斷進步。掌握密碼學基礎不僅有助於CTF競賽,更是現代信息安全的核心技能。

持續學習建議

  1. 理論與實踐並重
  2. 關注最新的密碼學進展
  3. 參與CTF競賽鍛煉技能
  4. 深入研究感興趣的特定領域

記住:密碼學不是萬能的,但沒有密碼學是萬萬不能的

💬 參與討論
使用 GitHub 帳號登入參與討論