繁体   English   中英

编码RSA算法Java

[英]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 他们保持断开连接。 如果稍后更改tempGCD将不知道并且也不会更改。 您需要直接将一个添加到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 ,它也会给出正确的结果。 也不难读,这对以后维护代码很有用。

存储什么

您还应该只存储ne (和d,但仅在它是私钥的情况下) 永远不要pqϕ与RSA一起存储,因为它们使您可以轻松地从公钥中找出私钥。

通常,不要在getZZZ方法中计算

您应该在构造函数方法中找出ne (和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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM