我对RSA的安全性有点困惑。我一直在谷歌上搜索rsa算法,发现了很多,但它们的密钥似乎一直都是小数字。
这是迄今为止我发现的最简单的算法:
void RSAEncDec(BYTE* pBuff, int iLen)
{
for (long i = 0; i < iLen; i++)
{
pBuff[i] = (long)pow(pBuff[i], key) % modl;
}
}
使用密钥生成算法:
rsacrypto::rsacrypto()
{
long p1,p2; //Prime numbers
long n = 0; //Modulus
long phi =0; //Totient value.
long e = 0; //Public key exponent.
long d = 0; //Private key exponent.
p1 = genrndprimes(100,900);
Sleep(1000);
p1 = genrndprimes(100,900);
n = p1*p2;
phi = totient(n);
e = genrndnum(2,(phi-1));
while(gcd(e,phi)!=1)
{
e = genrndnum(2,(phi-1));
}
d = (1/e)%phi; //Modular Multiplicative Inverse.
privatekey = e;
publickey = d;
modl = n;
}
我担心"genrndptimes(100900)",900之间的100是一个小数字,而我了解到密钥大小需要在512位以上,远远超过900。我是不是搞错了?
非常感谢。
这根本不安全,而且可以很快地进行暴力强制。从公钥中找到私钥最多需要900个除法(假设genrndprimes
取实际的最小值和最大值,而不是位数)。所以这只需要不到一秒钟的时间。
您需要编写自己的多精度代码,或者简单地使用现有的代码,如GMP。然后你可以表示大整数。今天,n的一个好的起始值是2048位整数。
此外,模乘逆不是实际的除法运算,因为不可能有任何分数。一切都必须用模运算来完成。例如,模乘逆需要使用扩展的欧氏算法来找到它
但是,要使RSA在现实世界中实际可用,您还需要实现一个填充方案,如PKCS#1v2.0(OAEP)。
然后,如果要加密大于n的数据,则需要研究混合加密(还必须考虑填充)。在这种情况下,您将生成一个随机AES密钥,用AES加密数据,然后用RSA加密生成的AES密钥,因为AES密钥足够小,可以加密。
完成所有这些之后,你会发现你的代码有漏洞,很容易受到各种侧通道攻击。您将使用您最喜欢的搜索引擎来找到一个现有的广为人知且经过测试的库,该库可以为您完成所有这些工作,因为永远不会推出您自己的加密。