RSA 加解密算法(c++\python\java)

RSA 加解密算法

RSA 是一种非对称加密算法,广泛应用于安全通信、数字签名、证书生成等场景。它的安全性基于大数分解的难度。在RSA算法中,用户生成一对公钥和私钥。公钥用于加密,而私钥用于解密。

RSA 算法的基本步骤:

  1. 密钥生成:

    • 选择两个大的质数 p p p q q q
    • 计算 n = p × q n = p \times q n=p×q
    • 计算欧拉函数 ϕ ( n ) = ( p − 1 ) × ( q − 1 ) \phi(n) = (p-1) \times (q-1) ϕ(n)=(p1)×(q1)
    • 选择整数 e e e,使得 1 < e < ϕ ( n ) 1 < e < \phi(n) 1<e<ϕ(n) e e e ϕ ( n ) \phi(n) ϕ(n) 是互质的。
    • 计算 d d d 作为 e e e ϕ ( n ) \phi(n) ϕ(n) 的乘法逆元,即 d × e ≡ 1 m o d    ϕ ( n ) d \times e \equiv 1 \mod \phi(n) d×e1modϕ(n)
    • 公钥为 ( e , n ) (e, n) (e,n),私钥为 ( d , n ) (d, n) (d,n)
  2. 加密:

    • M M M 是明文信息。
    • 计算密文 C C C C ≡ M e m o d    n C \equiv M^e \mod n CMemodn
  3. 解密:

    • 使用私钥 ( d , n ) (d, n) (d,n)
    • 计算 M ≡ C d m o d    n M \equiv C^d \mod n MCdmodn 来获取原始消息 M M M

C++ 实现:

下面是一个简化的 C++ 实现来展示 RSA 算法的核心概念:

// 引入所需的头文件
#include <iostream>  // 为了使用cout等C++标准输入输出功能
#include <cmath>     // 为了使用数学函数
#include <vector>    // 为了使用vector容器
#include <ctime>     // 为了使用时间函数
#include <cstdlib>   // 为了使用rand()和srand()

// 定义一个函数来计算 (a * b) % mod,避免大数溢出
long long modMultiply(long long a, long long b, long long mod) {
    long long result = 0;  // 初始化结果为0
    a = a % mod;           // 取模,确保a小于mod
    while (b) {            // 当b不为0时循环
        if (b & 1)                             // 如果b是奇数
            result = (result + a) % mod;       // 更新结果
        a = (a * 2) % mod;                     // 双倍增加a
        b /= 2;                                // 将b减半
    }
    return result % mod;   // 返回结果
}

// 定义一个函数来计算 (base^exponent) % mod
long long modPower(long long base, long long exponent, long long mod) {
    long long result = 1;  // 初始化结果为1
    base = base % mod;     // 取模,确保base小于mod
    while (exponent) {                             // 当exponent不为0时循环
        if (exponent & 1)                          // 如果exponent是奇数
            result = modMultiply(result, base, mod); // 更新结果
        exponent >>= 1;                            // 将exponent减半
        base = modMultiply(base, base, mod);       // 更新base的值
    }
    return result;   // 返回结果
}

// 定义一个函数判断给定的数是否为素数
bool isPrime(long long n) {
    if (n <= 1)                      // 如果n小于或等于1,返回false
        return false;
    if (n <= 3)                      // 如果n小于或等于3,返回true
        return true;
    if (n % 2 == 0 || n % 3 == 0)   // 如果n能被2或3整除,返回false
        return false;
    for (long long i = 5; i * i <= n; i += 6)  // 从5开始,每次增加6来检查n是否是素数
        if (n % i == 0 || n % (i + 2) == 0)   // 如果n能被i或i+2整除,返回false
            return false;
    return true;   // 如果上述条件都不满足,返回true
}

// 定义一个函数来计算两个数的最大公约数
long long gcd(long long a, long long b) {
    if (!b)          // 如果b为0,返回a
        return a;
    return gcd(b, a % b);  // 否则,递归调用自身
}

// 定义一个函数使用扩展欧几里得算法来求解ax + by = gcd(a, b)
long long extendedEuclid(long long a, long long b, long long &x, long long &y) {
    if (b == 0) {     // 如果b为0,基本情况
        x = 1;
        y = 0;
        return a;
    }
    long long x1, y1;
    long long gcd = extendedEuclid(b, a % b, x1, y1);  // 递归调用
    x = y1;
    y = x1 - (a / b) * y1;
    return gcd;
}

// 定义一个函数来计算给定整数a关于模m的模逆
long long modInverse(long long a, long long m) {
    long long x, y;
    long long g = extendedEuclid(a, m, x, y);  // 使用扩展欧几里得算法
    if (g != 1)       // 如果gcd(a, m)不是1,那么逆不存在
        return -1;
    return (x % m + m) % m;  // 返回模逆
}

// 主程序入口
int main() {
    srand(time(NULL));  // 初始化随机数种子

    long long p, q;
    do {
        p = rand() % 50 + 1; // 随机生成一个小于50的数,用于演示
    } while (!isPrime(p));  // 保证p是素数

    do {
        q = rand() % 50 + 1; // 同上,为q做同样的处理
    } while (!isPrime(q));

    long long n = p * q;                    // 计算n = p * q
    long long phi = (p - 1) * (q - 1);      // 计算欧拉函数值phi

    long long e;
    do {
        e = rand() % phi;  // 生成一个随机数e
    } while (gcd(e, phi) != 1);  // 保证e和phi是互质的

    long long d = modInverse(e, phi);  // 计算模逆,也就是私钥d

    // 输出公钥和私钥
    std::cout << "Public Key (n, e): (" << n << ", " << e << ")" << std::endl;
    std::cout << "Private Key (n, d): (" << n << ", " << d << ")" << std::endl;

    long long message = rand() % n;  // 随机生成一个消息
    std::cout << "Original Message: " << message << std::endl;

    // 使用公钥e进行加密
    long long encryptedMessage = modPower(message, e, n);
    std::cout << "Encrypted Message: " << encryptedMessage << std::endl;

    // 使用私钥d进行解密
    long long decryptedMessage = modPower(encryptedMessage, d, n);
    std::cout << "Decrypted Message: " << decryptedMessage << std::endl;

    return 0;  // 结束程序
}

python 实现:

import random

def mod_power(base, exponent, mod):
    """计算 (base^exponent) % mod"""
    result = 1
    base = base % mod
    while exponent > 0:
        if exponent % 2:
            result = (result * base) % mod
        exponent >>= 1
        base = (base * base) % mod
    return result

def is_prime(n):
    """判断 n 是否为素数"""
    if n <= 1:
        return False
    if n <= 3:
        return True
    if n % 2 == 0 or n % 3 == 0:
        return False
    i = 5
    while i * i <= n:
        if n % i == 0 or n % (i + 2) == 0:
            return False
        i += 6
    return True

def gcd(a, b):
    """计算最大公约数"""
    while b:
        a, b = b, a % b
    return a

def extended_euclid(a, m):
    """使用扩展欧几里得算法来找到模逆"""
    if m == 0:
        return (1, 0)
    x1, y1 = extended_euclid(m, a % m)
    x, y = y1, x1 - (a // m) * y1
    return x, y

def mod_inverse(a, m):
    """计算给定整数a关于模m的模逆"""
    x, y = extended_euclid(a, m)
    return (x % m + m) % m

def generate_keys():
    """生成 RSA 密钥对"""
    p = q = 1
    while not is_prime(p):
        p = random.randint(2, 100) # 为了简化,这里选择的范围较小
    while not is_prime(q) or q == p:
        q = random.randint(2, 100)
    
    n = p * q
    phi = (p - 1) * (q - 1)

    e = random.randint(2, phi)
    while gcd(e, phi) != 1:
        e = random.randint(2, phi)

    d = mod_inverse(e, phi)
    
    return ((e, n), (d, n))

def encrypt(message, pub_key):
    """使用公钥加密消息"""
    e, n = pub_key
    return mod_power(message, e, n)

def decrypt(ciphertext, priv_key):
    """使用私钥解密密文"""
    d, n = priv_key
    return mod_power(ciphertext, d, n)

if __name__ == "__main__":
    public_key, private_key = generate_keys()
    print("Public Key:", public_key)
    print("Private Key:", private_key)

    message = random.randint(2, public_key[1] - 1)
    print("\nOriginal Message:", message)

    encrypted_message = encrypt(message, public_key)
    print("Encrypted Message:", encrypted_message)

    decrypted_message = decrypt(encrypted_message, private_key)
    print("Decrypted Message:", decrypted_message)

java 实现:

import java.math.BigInteger;
import java.util.Random;

public class RSA {

    private BigInteger n, d, e;

    private int bitlength = 1024;
    private Random r;

    public RSA() {
        r = new Random();
        BigInteger p = BigInteger.probablePrime(bitlength, r);
        BigInteger q = BigInteger.probablePrime(bitlength, r);

        n = p.multiply(q);

        BigInteger m = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));

        e = BigInteger.probablePrime(bitlength / 2, r);

        while (m.gcd(e).compareTo(BigInteger.ONE) > 0 && e.compareTo(m) < 0) {
            e.add(BigInteger.ONE);
        }

        d = e.modInverse(m);
    }

    public RSA(BigInteger e, BigInteger d, BigInteger n) {
        this.e = e;
        this.d = d;
        this.n = n;
    }

    public static void main(String[] args) {
        RSA rsa = new RSA();

        String testString = "Hello, RSA!";
        System.out.println("Encrypting: " + testString);
        byte[] encrypted = rsa.encrypt(testString.getBytes());
        byte[] decrypted = rsa.decrypt(encrypted);
        System.out.println("Decrypted: " + new String(decrypted));
    }

    public byte[] encrypt(byte[] message) {
        return (new BigInteger(message)).modPow(e, n).toByteArray();
    }

    public byte[] decrypt(byte[] message) {
        return (new BigInteger(message)).modPow(d, n).toByteArray();
    }
}


总结:

RSA 是现代密码学中的一块基石。它的魅力在于它的数学基础和它的双密钥系统,使得加密和解密使用不同的密钥。尽管上面的实现是为了教学目的,并不适用于实际的加密任务,但它为理解 RSA 提供了一个很好的起点。


希望这篇博客可以帮助你理解 RSA 加密算法的基础概念和它的工作原理。喜欢的话给博主点个赞吧!谢谢!

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值