密码学笔记

密码学


一、密码学基础概念

1. CIA三要素

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

2. 密码学与隐写的区别

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

二、古典密码

1. 凯撒密码

  • 原理 :字母表固定偏移(如偏移3)。
    • 加密公式:密文字母 = (明文字母 + 3) mod 26
    • 例子:A → D,HELLO → 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. 欧拉定理

  • 核心公式 :若 a 与 n 互质,则 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 是质数且 a 与 p 互质,则 a^(p-1) ≡ 1 (mod p)。
    • 例子:3^6 mod 7 = 729 mod 7 = 1。

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

  • 目标 :找到整数 x, y 使得 ax + by = gcd(a, b)。
  • 逆元 :若 a 与 m 互质,则存在 b 使得 a×b ≡ 1 (mod m),称 b 是 a 的模 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. 选两个大质数 p 和 q(如 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=11 → n=33, φ(n)=20。
  • 选 e=3(与20互质)。
  • 计算 d=7(因为 3×7=21 ≡1 mod20)。

2. 加密与解密

  • 加密公式 :密文 c = m^e mod n(m 是明文)。
  • 解密公式 :明文 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 难以分解出 p 和 q)。
  • 攻击方式 :
    • 暴力分解(对小 n 有效)。
    • 量子计算的Shor算法(威胁大数分解)。

五、RSA常见攻击场景

1. 模数分解攻击

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

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) 加密,且 e1 和 e2 互质,可通过扩展欧几里得算法恢复明文。
  • 公式 :找到 a 和 b 使得 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 函数返回 a 和 b,使得 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("验签失败")  

相关推荐
懂点Tech6 小时前
ctfshow misc28:GIF 高度修改解题与脚本实现
开发语言·windows·python
comedate6 小时前
SMLib 的 Examples 导读:PyAPI / SM_API / SMLib 三组示例怎么读
python·cad·smlib·examples·sm_api
云和数据.ChenGuang6 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
摇滚侠6 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
川石课堂软件测试7 小时前
学习软件测试需掌握的一些知识
数据库·python·sql·功能测试·网络协议·mysql·http
万化冥合7 小时前
PyBox屏幕键盘如何辅助演示键盘操作?
python·计算机外设
车软学堂7 小时前
从测试转开发,到底要补什么
网络·人工智能·python·功能测试·单片机·车载系统·自动化
天空依然蔚蓝7 小时前
分享一个自动检测网站在线状态的python程序
python·运维开发·1024程序员节
岁月宁静8 小时前
一个 AI 项目从本地到上线,要经过哪些步骤?全流程讲清楚
python·docker·agent
codists9 小时前
《crafting interpreters》阅读笔记:p45-p45
python