密码学笔记

密码学


一、密码学基础概念

1. CIA三要素

  • 机密性 (Confidentiality) :信息不被未授权者访问。
    • 例子:用钥匙锁住日记本,只有你有钥匙。
  • 完整性 (Integrity) :信息在传输/存储中不被篡改。
    • 例子:快递包裹封条,若破损则可能被篡改。
  • 可用性 (Availability) :授权用户能随时访问资源。
    • 例子:银行系统需保证7×24小时服务。

2. 密码学与隐写的区别

  • 密码学:隐藏信息内容(如加密后的乱码)。
  • 隐写:隐藏信息存在性(如图片藏文字)。

二、古典密码

1. 凯撒密码

  • 原理 :字母表固定偏移(如偏移3)。
    • 加密公式:密文字母 = (明文字母 + 3) mod 26
    • 例子:A → DHELLO → KHOOR

Python代码示例

python 复制代码
def caesar_encrypt(text, shift):  
    result = ""  
    for char in text:  
        if char.isalpha():  
            base = ord('A') if char.isupper() else ord('a')  
            result += chr((ord(char) - base + shift) % 26 + base)  
        else:  
            result += char  
    return result  

print(caesar_encrypt("HELLO", 3))  # 输出:KHOOR  

代码解释

  • 遍历每个字符,计算偏移后的ASCII值。
  • mod 26确保字母循环(如Z + 3 → C)。

2. 栅栏密码

  • 原理 :将明文按行分组后按列读取。
    • 例子:明文THEQUICKBROWNFOX,分2栏:

      T E Q I C B O O X  
      H U K R W N F X  
      

      密文:TEQICBOOXHUKRWNX

Python代码示例

python 复制代码
def rail_fence_encrypt(text, rails):  
    fence = [[] for _ in range(rails)]  
    rail = 0  
    for char in text:  
        fence[rail].append(char)  
        rail = (rail + 1) % rails  
    return ''.join([''.join(row) for row in fence])  

print(rail_fence_encrypt("HELLOWORLD", 2))  # 输出:HLOOL ELWRD  

代码解释

  • 创建rails个空列表模拟栅栏。
  • 按顺序循环填入字符,最后按行拼接。

3. 摩斯密码

  • 原理 :用点(·)和划(−)表示字母。
    • 例子:SOS → ··· −−− ···

Python代码示例

python 复制代码
morse_code = {'A':'.-', 'B':'-...', 'S':'...', 'O':'---'}  
def to_morse(text):  
    return ' '.join([morse_code[c.upper()] for c in text if c.upper() in morse_code])  

print(to_morse("SOS"))  # 输出:... --- ...  

代码解释

  • 查表替换每个字符为对应的摩斯码。

三、数学基础

1. 模运算

  • 定义 :对整数取余数的运算,符号为 mod
    • 例子:17 mod 5 = 2(因为 17 ÷ 5 余 2)。
  • 同余关系 :若 a mod n = b mod n,则称 a ≡ b (mod n)
    • 例子:23 ≡ 65 (mod 7),因为两者余数均为 2。

应用场景:钟表时间(12小时制)、密码学中的循环计算。


2. 欧拉定理

  • 核心公式 :若 an 互质,则 a^φ(n) ≡ 1 (mod n)
    • φ(n)(欧拉函数):小于 n 且与 n 互质的正整数的个数。
    • 例子:若 n = 7(质数),则 φ(7) = 6

计算 φ(n)

  • n = p×q(p、q为不同质数),则 φ(n) = (p-1)(q-1)
  • 例子:n = 15 = 3×5,则 φ(15) = 2×4 = 8

3. 费马小定理

  • 特例 :若 p 是质数且 ap 互质,则 a^(p-1) ≡ 1 (mod p)
    • 例子:3^6 mod 7 = 729 mod 7 = 1

4. 扩展欧几里得算法(求逆元)

  • 目标 :找到整数 x, y 使得 ax + by = gcd(a, b)
  • 逆元 :若 am 互质,则存在 b 使得 a×b ≡ 1 (mod m),称 ba 的模 m 逆元。

Python代码示例

python 复制代码
def extended_gcd(a, b):  
    if b == 0:  
        return a, 1, 0  
    else:  
        g, x, y = extended_gcd(b, a % b)  
        return g, y, x - (a // b) * y  

a, m = 3, 11  
g, x, y = extended_gcd(a, m)  
if g == 1:  
    inverse = x % m  
    print(f"3的模11逆元是 {inverse}")  # 输出:4(因为 3×4=12 ≡1 mod11)  

代码解释

  • 递归计算最大公约数 g 和系数 x, y
  • g=1,则 x % m 即为 a 的逆元。

四、RSA算法

1. 密钥生成步骤

  1. 选两个大质数 pq(如 512位)。
  2. 计算模数 n = p×q
  3. 计算欧拉函数 φ(n) = (p-1)(q-1)
  4. 选公钥 e,满足 1 < e < φ(n)eφ(n) 互质。
  5. 计算私钥 d,即 d ≡ e⁻¹ (mod φ(n))
  6. 公钥为 (n, e),私钥为 (n, d)

示例

  • p=3, q=11n=33, φ(n)=20
  • e=3(与20互质)。
  • 计算 d=7(因为 3×7=21 ≡1 mod20)。

2. 加密与解密

  • 加密公式密文 c = m^e mod nm 是明文)。
  • 解密公式明文 m = c^d mod n

Python代码示例

python 复制代码
from Crypto.Util.number import getPrime, inverse  

# 密钥生成  
p = getPrime(10)  # 生成10位质数  
q = getPrime(10)  
n = p * q  
phi = (p-1) * (q-1)  
e = 65537  # 常用公钥  
d = inverse(e, phi)  

# 加密  
m = 42  
c = pow(m, e, n)  

# 解密  
m_decrypted = pow(c, d, n)  
print(f"明文: {m}, 解密结果: {m_decrypted}")  # 输出:42  

代码解释

  • getPrime 生成质数,inverse 计算逆元。
  • pow(c, d, n) 高效计算大数幂取模。

3. 安全性原理

  • 核心难点 :大整数分解问题(已知 n 难以分解出 pq)。
  • 攻击方式
    • 暴力分解(对小 n 有效)。
    • 量子计算的Shor算法(威胁大数分解)。

五、RSA常见攻击场景

1. 模数分解攻击

  • 原理 :若模数 n 过小或存在特殊结构(如 pq 接近),可通过分解 n 恢复私钥。
  • 工具yafufactordbsagemath
  • 示例 (费马分解):
    • n = p×q,且 pq 接近,则 p ≈ √n
    • √n 开始搜索相邻素数,找到 pq

Python代码示例

python 复制代码
import gmpy2  

def fermat_factorization(n):  
    a = gmpy2.isqrt(n) + 1  
    b2 = a*a - n  
    while not gmpy2.is_square(b2):  
        a += 1  
        b2 = a*a - n  
    b = gmpy2.isqrt(b2)  
    return (a + b, a - b)  

n = 1234567891011121314151617181921  
p, q = fermat_factorization(n)  
print(f"p = {p}, q = {q}")  

代码解释

  • √n 开始逐步增加 a,计算 b² = a² - n,直到 b 为整数。

2. 共模攻击

  • 原理 :若同一明文用两个不同的公钥 (n, e1)(n, e2) 加密,且 e1e2 互质,可通过扩展欧几里得算法恢复明文。
  • 公式 :找到 ab 使得 a*e1 + b*e2 = 1,则 m = (c1^a * c2^b) mod n

Python代码示例

python 复制代码
from Crypto.Util.number import inverse  

n = 123456789  
e1, e2 = 3, 65537  
c1 = pow(m, e1, n)  
c2 = pow(m, e2, n)  

# 扩展欧几里得求a和b  
g, a, b = extended_gcd(e1, e2)  
m = (pow(c1, a, n) * pow(c2, b, n)) % n  
print(f"明文: {m}")  

代码解释

  • extended_gcd 函数返回 ab,使得 a*e1 + b*e2 = 1

3. 低加密指数攻击

  • 场景 :若公钥 e 极小(如 e=3),且明文 m 较小,则 m^e < n,可直接开方恢复明文。

  • 示例

    python 复制代码
    e = 3  
    c = m**e  # 假设n > m^e  
    m_decrypted = gmpy2.iroot(c, e)[0]  

六、对称密码(AES)

1. AES加密流程

  • 分组长度:128位(16字节)。
  • 核心步骤
    1. 轮密钥加(AddRoundKey):将密钥与数据异或。
    2. 字节替换(SubBytes):通过S盒替换每个字节。
    3. 行移位(ShiftRows):循环左移每一行。
    4. 列混淆(MixColumns):矩阵乘法混淆列数据。

Python代码示例(简化版)

python 复制代码
from Crypto.Cipher import AES  

key = b'0123456789abcdef'  
data = b'ThisIsASecretMsg'  

# 加密  
cipher = AES.new(key, AES.MODE_ECB)  
ciphertext = cipher.encrypt(data)  

# 解密  
plaintext = cipher.decrypt(ciphertext)  
print(f"解密结果: {plaintext}")  

代码解释

  • AES.MODE_ECB 表示电子密码本模式(无填充)。

2. AES的S盒与逆S盒

  • S盒:非线性替换表,将每个字节映射为另一个字节。
  • 逆S盒:解密时反向替换。
  • 生成规则:基于有限域乘法逆元和仿射变换。

七、流密码(RC4)

1. RC4算法流程

  1. 初始化S盒:填充0-255,并用密钥打乱顺序。
  2. 生成密钥流:通过交换S盒元素生成伪随机序列。

Python代码示例

python 复制代码
def rc4(key):  
    S = list(range(256))  
    j = 0  
    # 初始化S盒  
    for i in range(256):  
        j = (j + S[i] + key[i % len(key)]) % 256  
        S[i], S[j] = S[j], S[i]  
    # 生成密钥流  
    i = j = 0  
    while True:  
        i = (i + 1) % 256  
        j = (j + S[i]) % 256  
        S[i], S[j] = S[j], S[i]  
        K = S[(S[i] + S[j]) % 256]  
        yield K  

key = b'SecretKey'  
plaintext = b'HelloWorld'  
keystream = rc4(key)  
ciphertext = bytes([p ^ next(keystream) for p in plaintext])  
print(f"密文: {ciphertext}")  

代码解释

  • 初始化阶段通过密钥打乱S盒,生成阶段动态交换元素并输出密钥流。

八、证书格式解析

1. PEM与DER格式

  • PEM :以 -----BEGIN/END 包裹的Base64编码文本,常用于存储公钥/私钥。

    -----BEGIN PUBLIC KEY-----  
    MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQ...  
    -----END PUBLIC KEY-----  
    
  • DER:二进制格式,适用于程序直接解析。

2. 格式转换(OpenSSL)

  • PEM转DER

    bash 复制代码
    openssl rsa -in public.pem -inform PEM -outform DER -out public.der  
  • DER转PEM

    bash 复制代码
    openssl rsa -in public.der -inform DER -outform PEM -out public.pem  

3. Python解析证书

python 复制代码
from Crypto.PublicKey import RSA  

# 读取PEM证书  
with open("public.pem", "r") as f:  
    pem_data = f.read()  
key = RSA.import_key(pem_data)  
print(f"模数n={key.n}, 公钥e={key.e}")  

代码解释

  • RSA.import_key 可直接解析PEM格式的公钥/私钥。

九、编码方式

1. Base64编码

  • 原理:将二进制数据按6位分组,映射到64个可打印字符(A-Z, a-z, 0-9, +/)。

  • 示例

    python 复制代码
    import base64  
    data = b"Hello, Crypto!"  
    encoded = base64.b64encode(data).decode()  # SGVsbG8sIENyeXB0byE=  
    decoded = base64.b64decode(encoded)       # b'Hello, Crypto!'  

2. URL编码

  • 原理 :将特殊字符替换为 % 后跟十六进制值(如空格→%20)。

  • 示例

    python 复制代码
    from urllib.parse import quote, unquote  
    url = "flag{hello world}"  
    encoded = quote(url)        # flag%7Bhello%20world%7D  
    decoded = unquote(encoded)  # flag{hello world}  

3. Quoted-printable编码

  • 原理 :非ASCII字符用 =XX 表示(如 =E4=B8=AD)。

  • 示例

    python 复制代码
    import quopri  
    text = "flag{中文}"  
    encoded = quopri.encodestring(text.encode()).decode()  # flag=E4=B8=AD=E6=96=87  
    decoded = quopri.decodestring(encoded)                 # b'flag{中文}'  

十、现代密码学工具总结

1. 常用工具

  • OpenSSL :命令行工具,支持证书生成、格式转换、加解密。

    bash 复制代码
    # 生成RSA私钥  
    openssl genpkey -algorithm RSA -out private.pem  
    # 提取公钥  
    openssl rsa -pubout -in private.pem -out public.pem  
  • PyCryptodome :Python密码学库,支持AES、RSA、哈希等。

    python 复制代码
    from Crypto.Cipher import AES  
    cipher = AES.new(key, AES.MODE_GCM)  # AES-GCM模式加密  
  • hashlib :Python标准库,支持SHA256、MD5等哈希算法。

    python 复制代码
    import hashlib  
    hash_obj = hashlib.sha256(b"data").hexdigest()  

2. 在线工具


十一、补充知识点

1. 哈希函数

  • 特性:单向性、抗碰撞性。

  • 应用场景 :文件完整性校验、密码存储。

    python 复制代码
    import hashlib  
    password = "123456".encode()  
    salt = os.urandom(16)  
    hashed = hashlib.pbkdf2_hmac("sha256", password, salt, 100000)  

2. 数字签名

  • 流程

    1. 发送方用私钥签名数据。
    2. 接收方用公钥验证签名。
  • 示例(RSA签名)

    python 复制代码
    from Crypto.Signature import pkcs1_15  
    from Crypto.Hash import SHA256  
    
    # 签名  
    hash_obj = SHA256.new(data)  
    signature = pkcs1_15.new(private_key).sign(hash_obj)  
    
    # 验签  
    try:  
        pkcs1_15.new(public_key).verify(hash_obj, signature)  
        print("验签成功")  
    except (ValueError, TypeError):  
        print("验签失败")  

  • 流程

    1. 发送方用私钥签名数据。
    2. 接收方用公钥验证签名。
  • 示例(RSA签名)

    python 复制代码
    from Crypto.Signature import pkcs1_15  
    from Crypto.Hash import SHA256  
    
    # 签名  
    hash_obj = SHA256.new(data)  
    signature = pkcs1_15.new(private_key).sign(hash_obj)  
    
    # 验签  
    try:  
        pkcs1_15.new(public_key).verify(hash_obj, signature)  
        print("验签成功")  
    except (ValueError, TypeError):  
        print("验签失败")  

相关推荐
Long_poem15 分钟前
【自学笔记】R语言基础知识点总览-持续更新
开发语言·笔记·r语言
一只积极向上的小咸鱼26 分钟前
PyTorch 和 Python关系
人工智能·pytorch·python
m0_748255021 小时前
python的sql解析库-sqlparse
数据库·python·sql
小爬虫程序猿1 小时前
衣联网的商品列表页面结构是怎样的?
开发语言·爬虫·python
dlhto2 小时前
Ollama+ WebUI 部署deepseek-r1
linux·python·语言模型
东东oyey2 小时前
Prompt 工程
python·llm·prompt·提示词工程
九溪弥烟、3 小时前
python编写的一个打砖块小游戏
开发语言·python·pygame
stars3 小时前
搞定python之三----序列、字典及集合
开发语言·python
Matrix703 小时前
Scala编程_实现Rational的基本操作
开发语言·python·scala
qq_257379593 小时前
python基础-字符串速查笔记
开发语言·笔记·python