【发布时间】:2016-05-12 00:12:31
【问题描述】:
我一直在对 RSA 加密系统进行一些研究,使用小素数编写代码非常简单,因为没有太多可能性,性能也不是真正的问题。
RSA 的工作原理如下:
-
首先,您生成一个
n值,从随机选取的 2 个素数中得到乘积:n = p * q-
然后你需要你的公钥,称为e。它可以是任何与 φ(n) 互质的数:
mcd(φ(n), e) = 1
根据欧拉函数,
φ(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。根据this page,它们是素数。
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,因为使用的值非常大。
理论上,一切正常。实际上,@ 987654352@,所以检查@ 987654353@,如果没有在e 上加1,然后再试一次,这不是一个选择。该程序从 30 分钟开始运行,平均每秒 150.000 个数字。 e = 548151505 仍然找不到 mcd(pn, e) = 1。
有什么方法可以在合理的时间内找到e?
【问题讨论】:
-
扩展欧几里得算法不就是这样吗? en.wikipedia.org/wiki/Extended_Euclidean_algorithm
-
没有
mcd这样的东西。也许你打错了,因为它是gcd或欧几里得算法。 -
这是从公钥(e)获取私钥(d),这是下一步,可以通过d(mod n)= e^-1来完成。我要做的是生成 e,公钥。
-
@ArtjomB 完全一样,只是在我的国家它被称为 mcd(maximo comun divisor),它是 gcd(最大公约数)的西班牙语翻译。
-
正如 user448810 回答的那样,您不需要找到 e,只需将其设置为某个常用值即可。如果你真的有兴趣找到一个“独特的”e,那么这个问题可能更适合Mathematics 或Cryptography。请检查是否已经有类似的问题被问到。选择 Fermat Primes 作为 e 是有原因的,即设置的位数必须很低才能进行快速加密和快速签名验证。
标签: java math rsa arithmetic-expressions modular-arithmetic