原文链接 mp.weixin.qq.com/s/r7H82DC8L…
title: RSA加密算法中的公钥密钥 date: 2023-08-26 23:38:31 tags: '密码技术,读书笔记'
在昨天的文章RSA加密算法中提到了两个关键词——公钥、私钥。并且我们知道了,RSA 的加密就是求“明文的E次方 mod N”,解密是求“密文的D次方 mod N”。那么公式中的E、D、N这三个数就是生成的密钥对。
这三个数字肯定不是随随便便就拿来用的,那样的话加密也太容易被激活成功教程了。它们有自己的生成方式。
我们先来简单陈述一下RSA密钥对的生成步骤,这其中涉及到了一些数学原理,暂时现不用知道什么意思。因为我也一知半解
经过上述五个步骤,我们已经成功按照规则生成了RSA 的公钥和私钥,现在来详细解释一下让我们迷糊的名词和公式符号
选择两个互质的数字,p 和 q。什么是质数呢?
第三步中提到了一个函数符号——φ(n)。这个φ符号表示:“欧拉函数”。那什么是“欧拉函数”?
欧拉函数 φ是以欧拉命名的一个数论函数。它表示对于一个正整数m,在小于等于m的正整数中与m互质的正整数的个数。(维基百科)
(n)代表了一个正整数n。φ(n) 合起来表达的意思是:对于给定的正整数n,计算小于等于n并且与n本身互为质数的正整数个数。上面这两句话读起来很难理解,每个字都认识,但是连起来的意思总觉得模模糊糊。下面举个例子:
当 n =10 ,φ(n) = 4。为什么呢?因为:小于等于10的正整数有:1,2,3,4,5,6,7,8,9,10
其中与10互质的有:1,3,7,9。所以 φ(n) = 4。
现在上述步骤中难以理解的公式和名词都解释了, 我们尝试来生成一个RSA 的密钥对。
按照步骤我们应该先选择两个大的随机的质数, 这里我们选择p = 3, q = 13
第二步中N = p * q ,则N = 3 *13 = 39
第三步骤计算:φ(n)= (p-1)*(q-1) ,把p = 3, q = 13代入到公式中计算得出φ(n)= 24.这表示当N等于39的时候,与39互质的整数的个数是24。现在我们知道φ(n)=24,那么就可以计算第四步骤中的E
E的计算规则是大于1但是小于 φ(n) 并且与 φ(n)互为质数。公式表示就是 1 < E < φ(n) , 我们知道了φ(n) = 24,所以E 这个数字的取值范围就是 1、5、7、11、13、17 ....我们可以看出有很多数字,但是并不是都满足条件,我们选择11这个数字作为E 的值。
到此,我们已经计算出了E = 11 ,N = 24。这两个数字将作为我们的公钥。
因为N这个数字公钥私钥都会用到,所以接下来我们只需要计算D就可以了。
第五步中D的计算公式为:(E * D) % φ(N) = 1,E = 11,D 未知,φ(N) = 24。经过计算得出:D = 23
“
我们想要找到一个值 D,使得以下方程成立: (E * D) % φ(N) = 1;好像是废话
使用扩展欧几里德算法计算 11 和24的最大公约数(GCD):
要求求解D的值。 具体计算步骤如下: 计算11与24的最大公约数 gcd(11,24) = 1 因为gcd(11,24)=1,所以方程有解 使用扩展欧几里得算法求11对24的模反元素D: 设:r0 = 24 r1 = 11 r2 = r0 % r1 = 24 % 11 = 2 递归计算: r3 = r1 % r2 = 11 % 2 = 1 r4 = r2 % r3 = 2 % 1 = 0 得到:r3 = gcd(11,24) = 1 所以11对24的模反元素是r2的值,即: D = 2 将D=2代入原方程验证: (11 * 2) mod 24 = 22 结果不是1,所以D≠2。 继续递归计算: r5 = r3 % r4 = 1 % 0 = 1 r6 = r4 % r5 = 0 % 1 = 0 得到:r5 = gcd(11,24) = 1 所以11对24的模反元素是r4的值,即: D = 23 重新验证: (11 * 23) mod 24 = 1 综上,在给定的方程 11 * D mod 24 = 1 中,D=23。
我自己按照维基百科的方法计算了三遍,都不对,最后求助了GPT。😆
”
现在我们终于把公钥私钥都计算完了。
公钥:E = 11 , N = 39
私钥:D = 23 , N = 39
我们现在是用自己计算出来的公钥加密一段数字试试,RSA 的明文规则是小于N 的数,所以。我们取明文为8。代入加密公式:密文 = 明文E mod N 8 11 mod 39 = 5, 得到密文为5
将 20 代入到解密公式:明文 = 密文D mod N 5 23 mod 39 = 8, 得到明文为8
/** * 上述代码首先初始化了基数 datai,指数 ED 和模数 N,然后定义了一个变量 result 存储计算结果。 * 接着,代码使用一个 for 循环,循环次数为指数的值。在每次循环中,都会将 result 乘以基数, * 然后对模数取模,以此来实现 (a*b)%c = (a%c * b%c)%c 这个公式。最后,代码打印出结果。 * @param datai * @param ED * @param N * @return */
private static long mod(int data, int ED, int N) {
long result = 1;
for (int j = 0; j < i1; j++) {
result = result * i % i2;
}
return result;
}