密码学|公钥密码

公钥密码概述

加密与解密使用不同密钥,分公钥与私钥
公钥密码体制安全性依赖于计算困难问题,
单向函数\((OWF--one way function)\): 由x计算\(y=f(x)\)是容易的,但反之是计算困难的
计算难易以计算复杂性理论为依据
陷门\((trapdoor)\)单向函数: 有陷门(私钥)可以求\(f\)的逆,用于构造单向函数的计算困难问题。

  • 大数分解 (factering):求\(N=p*q\)中的\(p\)\(q\)
  • 离散对数\((DL)\): 求\(y= g^xmod p\)\(x\)
  • 椭圆曲线上离散对数: 求\(y=xP\)\(x\)
  • 二次剩余\((QR)\): 求\(y = x^2 modN\)\(x\)
    -\(Diffe-Hullman\)问题\((DH)\)\(g^xg^y ↛ g^{xy}\)
  • 椭圆曲线上双线性对\(( pairing )\)的问题

公钥密码的计算都在相应的代数结构中进行

RSA

基于数论中大整数分解的困难性

密钥生成 (Key Generation)

  1. 随机选择两个不同的大素数,记为\(p\)\(q\)。这两个素数需要足够大,必须保密
  2. 计算\(n = p * q\)\(n\)将作为公钥和私钥的一部分,是加密和解密运算的模数。\(n\)的长度(以位为单位)通常决定了RSA密钥的强度
  3. 计算欧拉函数\(φ(n) = (p - 1) * (q - 1)\)。这个值用于后续计算,但不会直接出现在公钥或私钥中,必须保密。
  4. 选择公钥指数\(e\),满足:
    • \(1 < e < φ(n)\)
    • \(e\)\(φ(n)\)互质,即\(gcd(e, φ(n)) = 1\)
    • 通常选择一些固定的值,如 e = 65537(即 0x10001),
  5. 计算私钥指数\(d\),使得\(d\)\(e\)关于模\(φ(n)\)的乘法逆元。也就是说,需要找到一个\(d\)满足:
    • \(e * d ≡ 1 (mod φ(n))\)
    • 或者等价地,\(e * d = k * φ(n) + 1\),其中\(k\)是某个整数
    • \(d\)通过扩展欧几里得算法。\(d\)必须保密
  6. 生成密钥对:
    • 公钥:\((e, n)\)可以安全地公开分享
    • 私钥:\((d, n)\)必须严格保密

加密 (Encryption)

假设Alice想给Bob发送一条加密消息,她需要使用Bob的公钥

  1. Alice获取Bob的公钥\((e, n)\)
  2. Alice将要发送的消息\(M\)转换为一个整数\(m\)。这个整数\(m\)必须满足\(0 ≤ m < n\)。如果原始消息太大,需要使用填充方案将其分割或编码成符合要求的块
  3. 计算密文\(c ≡ m^e (mod n)\)

解密 (Decryption)

Bob收到密文\(c\)后,使用自己的私钥来恢复原始消息。

  1. Bob使用自己的私钥\((d, n)\)
  2. 计算明文对应的整数\(m' ≡ c^d (mod n)\)
  3. Bob将整数\(m'\)转换回原始的消息\(M\)

实现

https://www.cnblogs.com/luminescence/p/18931824

RSA的计算

加解密的计算证明

如果\(m\)\(n\)互质,那么\(m^φ(n) ≡ 1 (mod n)\)
\(e * d ≡ 1 (mod φ(n))\),所以存在整数\(k\)使得\(e * d = k * φ(n) + 1\)
\(m ≡ c^d ≡ (m^e)^d ≡ m^{(e*d)} ≡ m^{(k*φ(n) + 1)} ≡ (m^{φ(n)})^k * m^1 ≡ 1^k * m ≡ m (mod n)\)

模逆算法

拓展欧几里得算法Extended Euclidean Algorithm
通过贝组等式找到乘法逆元
\(a \cdot x + b \cdot y = \gcd(a, b)\)

  1. 递归形式
    • 基础情况:如果\(b = 0\),则\(\gcd(a, b) = a\),此时\(x = 1\)\(y = 0\)
    • 递归步骤:假设\(\gcd(b, a \mod b) = x' \cdot b + y' \cdot (a \mod b)\),则:
      \(\gcd(a, b) = x' \cdot b + y' \cdot (a - \lfloor a/b \rfloor \cdot b) = y' \cdot a + (x' - \lfloor a/b \rfloor \cdot y') \cdot b\)
      因此,新的\(x = y'\)\(y = x' - \lfloor a/b \rfloor \cdot y'\)
  2. 迭代形式
    • 初始化:\(x = 1\),\(y = 0\),\(x' = 0\),\(y' = 1\)
    • 循环:当\(b \neq 0\)时:
      • 计算\(q = \lfloor a / b \rfloor\)\(r = a \mod b\)
      • 更新\(a = b\)\(b = r\)
      • 更新\((x, y, x', y') = (x' - q \cdot x, y' - q \cdot y, x, y)\)
        \({a}*{x} + {b}*{y} = gcd(a,b)\)
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

\(gcd(a,b) = 1\)时,即求a在模b下的乘法逆元

快速模幂运算

\(𝒎^𝒅mod𝒏\)快速算法步骤:
1、将指数d表示为二进制\(a_{k-1}⋯a_1a_0\)
2、令\(x = 1, y = m\)
3、迭代从下标 i = 0开始,
如果\(a_i = 1\),计算\(x = xy mod n\),\(y = y^𝟐 mod n\)
如果\(a_i = 0\),只计算\(y = y^2 mod n\)
4、迭代至\(k-1\),最后结果就是此时的\(x\)

def fast_modular_exponentiation(m, d, n):
    """
    快速模幂运算
    """
    # 将指数d转换为二进制字符串
    binary_d = bin(d)[2:]  
    k = len(binary_d)  
    x = 1
    y = m % n  

    for i in range(k):
        a_i = int(binary_d[i])
        if a_i == 1:
            x = (x * y) % n
            y = (y * y) % n
        else:
            y = (y * y) % n

    return x

本质上是将次幂\(d\)转化为二的次幂和

例题

设在一个使用 RSA 体制的密码应用系统中,有两个用户 A 与 B 使用了相同模数为 161、且公钥(加密指数)分别为 5 与 7,你作为一个攻击者,当同时截获到用户 C 分别发给用户 A 与 B 的、加密同一消息\(m\)的密文\(c_1 = 27\)\(c_2 = 55\)时,试恢复出消息\(m\)
解:
由于\(e_A\)\(e_B\)互质(即\(\gcd(5, 7) = 1\)),可以利用扩展欧几里得算法求解方程\(5x + 7y = 1\),得到整数解\(x = 3\)\(y = -2\)。因此,消息\(m\)可以恢复为:
\(m \equiv (c_1)^x \cdot (c_2)^y \pmod{n}\)
代入值:
\(m \equiv 27^3 \cdot 55^{-2} \pmod{161}\)

\(27^3 \equiv 41 \pmod{161}\)

使用扩展欧几里得算法:
\(55^{-1} \equiv 41 \pmod{161}\)
\(55^{-2} = (55^{-1})^2 = 41^2 \mod 161\)
\(55^{-2} \equiv 71 \pmod{161}\)

代入:
\(m \equiv 13 \pmod{161}\)

ElGamal公钥加密算法

算法概述

基于离散对数问题的非对称加密算法
安全性依赖于在有限域中求解离散对数的困难性
特点在于每次加密后生成的密文不同,可以有效防止重放攻击。

给定\(g\)\(h = g^x \mod p\),求解\(x\)是困难的


具体步骤

密钥生成

  • 选择参数:
    • 选择一个大素数\(p\),并选择一个生成元\(g\)(即\(g\)是模\(p\)的本原元)
    • 随机选择一个整数\(x\)作为私钥,满足\(1 \leq x \leq p-2\)
    • 计算\(y = g^x \mod p\),其中\(y\)为公钥
  • 密钥组成
    • 公钥:\((p, g, y)\)
    • 私钥:\(x\)

加密过程

使用公钥\((p, g, y)\)对明文\(M\)进行加密

  • 选择随机数:随机选择一个整数\(k\),满足\(1 \leq k \leq p-2\),且\(k\)\(p-1\)互质。
  • 计算密文分量:
    • 计算\(C_1 = g^k \mod p\)
    • 计算\(C_2 = M \cdot y^k \mod p\)
  • 生成密文:密文为\((C_1, C_2)\)

解密过程

使用私钥\(x\)对密文\((C_1, C_2)\)进行解密

  • 计算共享密钥:\(K = C_1^x \mod p\)
  • 计算明文:\(M = C_2 \cdot K^{-1} \mod p\),其中\(K^{-1}\)\(K\)的模逆元。

Python实现

import random
from math import gcd
def power_mod(a, b, c):
    """模幂运算"""
    result = 1
    a = a % c
    while b > 0:
        if b % 2 == 1:
            result = (result * a) % c
        a = (a * a) % c
        b = b // 2
    return result
def generate_key(p, g):
    """生成密钥"""
    x = random.randint(1, p-2)  # 私钥
    y = power_mod(g, x, p)      # 公钥
    return (p, g, y), x
def encrypt(p, g, y, M):
    """加密"""
    k = random.randint(1, p-2)  
    C1 = power_mod(g, k, p)
    C2 = (M * power_mod(y, k, p)) % p
    return (C1, C2)
def decrypt(p, x, C1, C2):
    """解密"""
    K = power_mod(C1, x, p)
    K_inv = pow(K, -1, p)
    M = (C2 * K_inv) % p
    return M

椭圆曲线

椭圆曲线的定义

满足方程\(y^2 = x^3 + ax + b\)的点集,其中\(a\)\(b\)是常数,且满足判别式\(4a^3 + 27b^2 \neq 0\)这确保了曲线没有奇点(即曲线是光滑的)
密码学中椭圆曲线通常定义在有限域上

椭圆曲线上的运算

椭圆曲线上的运算主要包括点加法和点倍乘法

点加法

给定椭圆曲线上的两点\(P(x_1, y_1)\)\(Q(x_2, y_2)\),它们的和\(R(x_3, y_3)\)的计算方法如下:

  • 如果\(P \neq Q\)
    • 斜率\(\lambda = \frac{y_2 - y_1}{x_2 - x_1} \mod p\)
      -\(x_3 = \lambda^2 - x_1 - x_2 \mod p\)
      -\(y_3 = \lambda(x_1 - x_3) - y_1 \mod p\)
  • 如果\(P = Q\)(即点倍乘):
    • 斜率\(\lambda = \frac{3x_1^2 + a}{2y_1} \mod p\)
      -\(x_3 = \lambda^2 - 2x_1 \mod p\)
      -\(y_3 = \lambda(x_1 - x_3) - y_1 \mod p\)
  • 如果\(P = -Q\)(即\(x_1 = x_2\)\(y_1 = -y_2\)),则\(P + Q\)为无穷远点\(O\)

点倍乘法

点倍乘法是指将一个点\(P\)乘以一个标量\(k\),即计算\(kP\)
这实际上是通过反复的点加法实现的,例如\(3Q = Q + Q + Q\)
点倍乘法是椭圆曲线密码学中的核心运算,其安全性依赖于离散对数问题的困难性。

计算椭圆曲线上的点时,需要用到二次剩余

椭圆曲线ElGamal公钥密码体制

算法概述

是传统ElGamal算法在椭圆曲线上的扩展,利用椭圆曲线上的离散对数问题来保证安全性。与传统的ElGamal相比,ECElGamal在提供同等安全性的情况下,可以使用更短的密钥,因此效率更高,可以应用于计算和存储能力小的智能卡等。

密钥生成

  1. 选择一条定义在有限域\(\mathbb{F}_p\)上的椭圆曲线\(E\),并选择一个基点\(G\)(生成元),该点满足阶数\(n\)
  2. 生成私钥:随机选择一个整数\(d\)作为私钥,满足\(1 \leq d \leq n-1\)
  3. 计算公钥:计算\(Q = dG\),其中\(Q\)为公钥。

加密过程

假设发送方想要加密消息\(M\)(消息\(M\)必须是椭圆曲线上的一个点),步骤如下:

  1. 选择随机数:发送方随机选择一个整数\(k\),满足\(1 \leq k \leq n-1\)
  2. 计算密文:
    • 计算\(C_1 = kG\)
    • 计算\(C_2 = M + kQ\)(即\(C_2 = M + k(dG)\)
  3. 发送密文:发送方将密文\((C_1, C_2)\)发送给接收方

解密过程

接收方使用私钥\(d\)解密密文\((C_1, C_2)\)

  1. 计算\(S = dC_1 = d(kG) = k(dG) = kQ\)
  2. 计算明文\(M = C_2 - S = (M + kQ) - kQ = M\)

示例

假设椭圆曲线\(E\)定义为\(y^2 = x^3 + x + 1 \mod 23\),基点\(G = (1, 5)\),阶数\(n = 28\)

  • 密钥生成
    • 接收方选择私钥\(d = 6\),计算公钥\(Q = 6G\)
  • 加密
    • 发送方选择随机数\(k = 4\),计算\(C_1 = 4G\)\(C_2 = M + 4Q\)
  • 解密
    • 接收方计算\(S = 6C_1 = 6(4G) = 24G\),然后\(M = C_2 - S\)
posted @ 2025-06-17 14:18  lumiere_cloud  阅读(48)  评论(0)    收藏  举报