[英]Coding RSA Algorithm Java
因此,我正在尝试从头开始创建RSA算法。
到目前为止,我已经成功创建了选择两个素数的能力(在当前示例中,我的素数为11和13。然后,我通过执行px q来计算N。这使我得到143。
然后,转到我的public BigInteger findZ()
方法,该方法计算ϕ为(p-1)(q-1)。
使用这个新计算的ϕ,我想找到一个数字,或者创建一个跟随1 <(e)<ϕ或简单gcd(e,simple)= 1的e变量。因此,我最初将temp设置为等于常数ONE (等于1)+1满足范围。 但是,在进行连续的调试尝试之后,循环再也找不到GCD等于1的值,因为我必须使用BigInteger,所以我创建了一个表示该常量的值。 是否有一个原因?
这是我的代码。
import java.math.BigInteger;
public class RSA
{
//Intialize the variables.
private BigInteger p;
private BigInteger q;
private BigInteger n;
private BigInteger z;
final private BigInteger ONE = BigInteger.valueOf(1);
public BigInteger getP()
{
return p;
}
public BigInteger getQ()
{
return q;
}
//Computes N, which is just p*q.
public BigInteger findN()
{
n = p.multiply(q);
return p.multiply(q);
}
public BigInteger findZ()
{
long pMinusOne = p.intValue() - 1;
long qMinusOne = q.intValue() - 1;
z = BigInteger.valueOf(pMinusOne * qMinusOne);
return z;
}
public BigInteger getE()
{
int temp = ONE.intValue() + 1;
BigInteger GCD = BigInteger.valueOf(temp);
while (GCD.gcd(z).compareTo(ONE) != 0)
{
temp++;
}
e = BigInteger.valueOf(temp);
return e;
}
}
任何帮助是极大的赞赏。
谢谢!
由于您寻求帮助,因此我会回答您的问题并提供其他提示。
一个技巧是在仅检查相等性时使用equals()
而不是compareTo()
。 有时,这可以减少工作量,并且也更易于阅读。
代码中最大的错误是temp
用于设置GCD
的原始值,但是不会将temp
链接到GCD 。 他们保持断开连接。 如果稍后更改temp
, GCD
将不知道并且也不会更改。 您需要直接将一个添加到GCD
。 这是一些示例代码:
BigInteger e = BigInteger.valueOf(3);
while (! phi.gcd(e).equals(BigInteger.ONE)) {
e = e.add(BigInteger.ONE);
}
BigInteger
的方法 通过使用自己喜欢的搜索引擎并搜索BigInteger 8 API
,了解使用BigInteger
可以轻松完成的操作。 8适用于您正在使用的Java版本,因此可能会发生变化。 该API用于方法列表。
在搜索结果的早期,您应该找到此API页面 。 BigInteger
有很多不错且方便的方法,因此请检查一下。 它甚至具有一个构造函数,该构造函数将为您提供任意大小的BigInteger
(很可能是素数),这对于为新的随机RSA密钥生成素数非常有用。
BigInteger
的内置常量 不要重新创建以下常量(这些常量显示在上面的API页面中):
BigInteger.ZERO
BigInteger.ONE
BigInteger.TEN
BigInteger
适合long
否则切勿将其转换为long
您正在将BigInteger
转换为long
,这是一个坏主意,因为有很多BigInteger
都不适合long
,导致结果不正确。 为了确保正确性(比速度更重要), 请直接使用BigInteger
进行算术运算 。
当得到long
时,也intValue()
使用intValue()
。 使用longValueExact()
。 为此,请在获取int
时使用intValueExact()
。
因此,计算ϕ:
BigInteger pMinusOne = p.subtract(BigInteger.ONE);
BigInteger qMinusOne = q.subtract(BigInteger.ONE);
BigInteger phi = pMinusOne.multiply(qMinusOne);
现在您知道,即使对于更大的BigInteger
,它也会给出正确的结果。 也不难读,这对以后维护代码很有用。
您还应该只存储n和e (和d,但仅在它是私钥的情况下) 永远不要将p , q或ϕ与RSA一起存储,因为它们使您可以轻松地从公钥中找出私钥。
getZZZ
方法中计算 您应该在构造函数方法中找出n和e (和d,但只有在它是私钥的情况下),并将它们仅存储在实例变量中。 然后,您可以使用getN()
和getE()
方法来获取预先计算的实例变量。 例如(您不必使用此代码,这只是一个想法):
public class RSA {
private final BigInteger n;
private final BigInteger e;
private final BigInteger d;
public RSA(final BigInteger p, final BigInteger q) {
this.n = p.multiply(q);
// Calculate phi
final BigInteger pMinusOne = p.subtract(BigInteger.ONE);
final BigInteger qMinusOne = q.subtract(BigInteger.ONE);
final BigInteger phi = pMinusOne.multiply(qMinusOne);
// Calculate e
BigInteger e = BigInteger.valueOf(3L);
while (! phi.gcd(e).equals(BigInteger.ONE)) {
e = e.add(BigInteger.ONE);
}
this.e = e;
// Calculate d
this.d = e.modInverse(phi);
}
public BigInteger getN() {
return n;
}
public BigInteger getE() {
return e;
}
public BigInteger getD() {
return d;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.