【问题标题】:Java : Power Massive NumbersJava:大数的幂
【发布时间】:2017-11-06 11:32:15
【问题描述】:
import java.math.BigDecimal;
import java.math.BigInteger;
public class RSAEncryption {
public static void main(String[] args){
//STAGE ONE AND TWO
int p=61;
int q=53;
//STAGE THREE
Integer pq=p*q;
//STAGE FOUR
int pTotient=p-1;
int qTotient=q-1;
//STAGE FIVE
//  int finalTotient=pTotient*qTotient;
int finalTotient=780;
//STAGE SIX AND SEVEN
int e=0;
if((p>17)||(q>17)){
    e=17;
}else{
    e=7;
}
//STAGE EIGHT AND NINE
int d=0;
int count=0;
while ((e*d%finalTotient)!=1){
    d=d+1;
    count=count+1;
}
//STAGE TEN
int ed=e*d;
System.out.println("p = "+p);
System.out.println("q = "+q);
System.out.println("pq = "+pq);
System.out.println("final totient = "+finalTotient);
System.out.println("calculation of ed = "+ed);
System.out.println("d = "+d);
//ENCRYPTION
int message=65;
//PUBLIC KEY
int result00 = (int)Math.pow(message, e);
System.out.println(result00);
int testing00=result00%3233;
System.out.println(testing00);
BigInteger dd00=new BigInteger("65");
BigInteger test00=dd00.pow(17);
System.out.println("BigInteger Power Calc: "+test00);
int to100=test00.intValue();
int finalt=to100%3233;
System.out.println(to100);

从上面的代码可以看出我正在尝试用 Java 制作一个 RSA 加密算法。问题是Java“Math.pow()”内置的幂函数不够精确,最终输出“to100”应该等于2790。我不确定我错过了什么并花了几个月。

我也尝试过使用 BigInteger.pow() 但无济于事。我不确定为什么 BigInteger.pow() 方法不起作用。

我正在尝试获取 c :

c = 65^17 mod 3233 = 2790。如这里的示例所示:https://en.wikipedia.org/wiki/RSA_(cryptosystem)

【问题讨论】:

标签: java encryption rsa biginteger


【解决方案1】:

如果您使用 BigInteger 类,这一切都非常简单。

示例:

private static final BigInteger ONE = BigInteger.ONE;

public static void main(String[] args) {

    BigInteger p = BigInteger.valueOf(61);
    BigInteger q = BigInteger.valueOf(53);
    BigInteger pq = p.multiply(q);
    BigInteger finalTotient = p.subtract(ONE).multiply(q.subtract(ONE));
    BigInteger e = BigInteger.valueOf(17);
    BigInteger d = e.modInverse(finalTotient);
    BigInteger message = BigInteger.valueOf(65);
    BigInteger encrypted = message.modPow(e, pq);
    BigInteger decrypted = encrypted.modPow(d, pq);
}

【讨论】:

    【解决方案2】:

    您的代码无法正常工作有几个原因:

    1. Math.pow 使用 doubles,它只有 53 位精度,不足以容纳 103 位数字 6,599,743,590,836,592,050,933,837,890,625 (6517)。
    2. BigInteger#intValue 产生一个 int,它只有 32 位精度,更不适合 103 位数字。

    您有两个选择,都涉及留在BigIntegers:

    1. 慢方法:执行BigIntegermod操作:

      BigInteger n = new BigInteger("65");
      BigInteger p = n.pow(17);
      BigInteger m = new BigInteger("3233");
      BigInteger result = p.mod(m);
      
    2. 快速方法:执行BigIntegermodPow操作:

      BigInteger n = new BigInteger("65");
      BigInteger e = new BigInteger("17");
      BigInteger m = new BigInteger("3233");
      BigInteger result = n.modPow(e, m);
      

    【讨论】:

    • 最好只使用BigInteger.valueOf(long) 而不是构造函数BigInteger(String)
    • @OlivierGrégoire 我试图更通用,因为 RSA 可以使用比longs 可以容纳的更大的位大小(现在 2048 位密钥很常见)。
    猜你喜欢
    • 2012-01-07
    • 2020-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 2013-03-04
    相关资源
    最近更新 更多