我知道这可能是基本但我下周要参加考试,我想测试自己对RSA的了解。
我有一个非常简单的问题,我正在努力查看RSA的机制,我想测试是否可以在浏览器控制台中加密和解密消息。
RSA变量是:
var p = 11 //the first prime number
var q = 5 //the second prime number
var m=72 // the message
var n=55 // the RSA modulus, n = p*q
var e=7 // so (e,n) are the public key
var d=23 //so (d,n) are the private key
var fi_of_n=40 //the totient, fi_of_n = (p-1)*(q-1) = 40
要加密,我正在做:
var c = Math.pow(m,e)%n // m^e mod(n); c=8
我得到的等于8
然后我要解密,使用d如下:
var m2 = Math.pow(c,d)%n // c^d mod(n)
但结果是17!不像我预期的那样72。我不知道我做错了什么,我认为这是一个非常简单的例子。
我的公钥和私钥的值是在此视频中获得的值:https://www.youtube.com/watch?v=kYasb426Yjk
答案 0 :(得分:2)
RSA有一个限制,即只能加密严格小于模数的消息。您的72的消息对于您的模数55来说太大了。您可以看到加密和解密基本上起作用,因为17 = 72(mod 55)。
在JavaScript中,所有数字都是浮点数。有一个可以安全地表示为整数的最大数字:Number.MAX_SAFE_INTEGER = 9007199254740991
。如果电源操作的结果超过此值,则浮点操作的性质无法确保您获得正确的值。在加密和解密期间,这种截止可能会发生两次。
我们以m = 5
为例。 pow(5, 7) = 78125
小于9007199254740991
。这里没有截止点。现在,c = 25
Math.pow(25, 23) = 1.4210854715202004e+32
得到的8
远大于安全整数。当我们现在应用模运算符时,它将不会给出正确的结果,因为浮点分辨率不再是1。
例如,消息pow(m,e)
产生足够小的pow(c,d)
值,该值小于此最大安全整数值和得到的密文也产生足够小的{{1}它没有被切断的价值。
您应该使用大数(多精度)库来执行这些操作,或者使用可以表示任何整数的Python,只要您有足够的内存即可。如果你想在JavaScript中继续这样做,那么jsbn除了大数据库之外还会实现RSA。
答案 1 :(得分:0)
由于@Artjom B.和@ rakeb.void的评论我正在用我找到的解决方案回答我自己的问题。
由于使用Number.MAX_SAFE_INTEGER的Javascript限制的限制,无法使用所呈现的变量进行测试。
其中一个解决方案是使用多精度库,另一个解决方案是使用Python进行相同的测试。
我使用Python,因为我不想学习如何使用多精度库来测试。我制作的节目如下:
import math
p = 11
q = 5
m = 39
n = 55
e = 7
d = 23
fi_of_n = 40
print ("original: "+str(m))
cipher= pow(m,e)%n
print("cipher: "+str(cipher))
m2 = pow (cipher,d)%n
print("decrypted: "+str(m2))
print("----")
print("Are they equal? " + str(m == m2))
只要消息低于模数运算符n,它就可以工作。