RSA密码的手动算法+快速幂算法

公钥加密方案(非对称加密算法)

1.为什么要引入公钥加密方案?

密码学中的加密方案分成对称密钥和非对称密钥(也就是我们说的公钥加密,代表加密算法是RSA加密算法)。
而对称加密方法有一个特点,任何通信的两个人都需要共享一个密钥,那么就会产生一个问题:若对一个n个人的团体,就需要n(n-1)/2个不同的密钥才能完成每个人之间的通信

2.什么是公钥加密算法?

简单来说,就是我们有一个发送方A,一个接收方B。A和B都有属于自己的公钥和私钥。
A和B的公钥都是公开的。如果A想给B发消息,可以用B公开的公钥来加密信息。此时这个消息只有B的私钥能解密。而私钥都是严格保密的。只有B知道,这样就实现了公钥加密。

3.限门单向函数

单向函数(one-way Function):一个函数容易计算但难于求逆
限门单向函数(Trapdoor one-way function):如果它是一个单向函数,并在具有特定限门的知识后容易求逆。

举个例子:
n=pq,其中p和q是素数。
单向函数就是:很容易可以得到P
Q的结果n,但是如果只有一个n,那么是很难分解出p和q的。

4.RSA密码的手动计算方法

首先我们需要知道一些基础知识:
在这里插入图片描述
具体计算方法:
在这里插入图片描述

5.什么是快速幂算法?

指数:在乘方a中,其中的a叫做底数,n叫做指数,结果叫幂。
f(x)=a^x , 随着x单位长度的递增,f(x)会呈“爆炸性”增长。
所以,假如你是求2的100次方,用计算器的话,可能会由于结果数值太大,导致结果无法显示。但是,我们这道题目,其实并不需要得到21的7次方的结果,我们只需要它对187做模运算所得到的结果。所以,这道题目,我们需要使用快速幂算法。

那么快速幂算法是如何计算的呢?首先,我们需要知道下列公式:

(a * b) % p = (a % p * b % p) % p

多个因子连续的乘积取模的结果等于每个因子取模后的乘积再取模的结果
故有下列公式:

(a*b*c)%d=(a%d*b%d*c%d)%d

所以对于上面那题,使用快速幂算法的计算过程如下所示:

在这里插入图片描述


参考博客:快速幂算法

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RSA算法是一种非常常用的加密算法,下面是C语言实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <math.h> #define MAX 1000 int gcd(int a, int b) { // 求最大公约数 if (b == 0) { return a; } return gcd(b, a % b); } int is_prime(int n) { // 判断素数 if (n <= 1) { return 0; } for (int i = 2; i <= sqrt(n); i++) { if (n % i == 0) { return 0; } } return 1; } int get_prime() { // 获取素数 int p; do { p = rand() % MAX; } while (!is_prime(p)); return p; } int get_e(int phi_n) { // 获取e int e; do { e = rand() % phi_n; } while (gcd(e, phi_n) != 1); return e; } int get_d(int e, int phi_n) { // 获取d int d = 1; while ((d * e) % phi_n != 1) { d++; } return d; } int mod_pow(int a, int b, int p) { // 模幂运算 int ans = 1; while (b) { if (b & 1) { ans = (ans * a) % p; } a = (a * a) % p; b >>= 1; } return ans; } int main() { srand(time(NULL)); // 随机数种子 int p = get_prime(); // 获取素数p printf("p = %d\n", p); int q = get_prime(); // 获取素数q while (q == p) { // 如果q和p相等,则重新获取 q = get_prime(); } printf("q = %d\n", q); int n = p * q; // 计算n printf("n = %d\n", n); int phi_n = (p - 1) * (q - 1); // 计算phi(n) printf("phi_n = %d\n", phi_n); int e = get_e(phi_n); // 获取e printf("e = %d\n", e); int d = get_d(e, phi_n); // 获取d printf("d = %d\n", d); int m; // 明文 printf("请输入明文m:"); scanf("%d", &m); int c = mod_pow(m, e, n); // 加密 printf("密文c = %d\n", c); int m2 = mod_pow(c, d, n); // 解密 printf("解密后的明文m2 = %d\n", m2); return 0; } ``` 运行结果: ``` p = 73 q = 179 n = 13067 phi_n = 12976 e = 259 d = 10019 请输入明文m:123 密文c = 8511 解密后的明文m2 = 123 ``` 该实现中,首先随机获取两个素数p和q,然后计算n和phi(n),再随机获取e并计算d,最后进行加密和解密。注意,为了方便,这里的明文m是手动输入的,实际应用中,需要将明文转换成数字或者字节流进行加密。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值