我一直在研究RSA加密系统,使用小素数编码很简单,因为没有太多可能性,性能也不是真正的问题。
以下是RSA的工作原理:
首先,您生成一个n
值,从2个素数中随机选取产品:
n = p * q
然后您需要公钥,称为 e 。它可以是φ(n)的任何数量的互质:
mcd(φ(n),e)= 1
根据 Euler函数,φ(n) = (p-1)(q-1)
您仍然需要私钥d
,它与e on modulo **φ(n)
相反。
所以d * e = 1 (mod φ(n))
n
是您的私钥时,e
和d
是您的公开值。没有人应该知道p
或q
,因为这些值可以获得φ(n)
,并使用它来计算d
。M = m^e (mod n)
,其中m
是原始邮件,M
是加密邮件。因此,每个人都可以使用您的公共值向您发送您可以阅读的加密邮件。d
,因为它与e
相反,因此M^d = (m^e)^d = m (mod n)
。邮件可以解密,但只能使用d
。知道这一点,要加密消息我们只需要获得两个随机素数,计算n, e, d,
并制作我们的加密和解密方法。
理论上这看起来很简单,现在让我们把它变成java代码:
我首先选择两个随机素数,数字越大,加密越强。所以我会选择p = 1644623
和q = 1644751
。根据{{3}},它们是素数。
BigInteger p = new BigInteger("1644623");
BigInteger q = new BigInteger("1644751");
然后,在我的init方法中,我初始化n, e
和d:
BigInteger p = new BigInteger("1644623");
BigInteger q = new BigInteger("1644751");
BigInteger n;
BigInteger e;
BigInteger d;
void init() {
n = p.multiply(q);
BigInteger pn = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
e = n.subtract(pn);
while (!mcd(pn, e).equals(BigInteger.ONE)) {
e = e.add(BigInteger.ONE);
System.out.println(e);
}
d = e.modPow(new BigInteger("-1"), pn);
}
我使用BigInteger而不是long,因为使用的值非常大。
从理论上讲,一切正常。实际上,pn = 2704992034500
,因此检查是否mcd(pn, e) = 1
,如果没有向e
添加1,则再次尝试它不是一个选项。该程序运行30分钟,平均每秒150,000次。 e = 548151505
但仍未找到mcd(pn, e) = 1
。
有没有办法在合理的时间内找到e
?
答案 0 :(得分:2)
根据定义,任何素数都将与模数共同构成,因此您不需要搜索一个,只需选择一个素数。由于加密密钥是公共的,因此大多数RSA实现使用的东西可以很容易地计算模幂运算:3和65537 = 2 ** 16 + 1都是素数,并且两者都常用于加密密钥。