RSA算法:执行解密时无效的纯文本

时间:2019-01-25 12:51:08

标签: java cryptography bigdecimal

class Calculate
{
  double gcd(double a, double b)
  {
    if (b == 0)
    {
      return a;
    }
    return gcd(b, a % b);
  }

  Calculate()
  {
    Scanner sc = new Scanner(System.in);
    System.out.print("Enter values of p : ");
    double p = sc.nextDouble();
    System.out.print("\nEnter value of q : ");
    double q = sc.nextDouble();
    System.out.print("\nEnter Message: ");
    double m = sc.nextDouble();  // message

    double n = p * q;
    System.out.println("n = " + n);    // first part of the public key
    double phi = (p - 1) * (q - 1);
    System.out.println("phi = " + phi);

    // assuming e = 3 
    double e = 3;        // second part of the public key

    // e must be relatively prime and smaller than phi
    while (e < phi)
    {
      if (gcd(e, phi) == 1)
      {
        break;
      }
      else
      {
        e++;
      }
    }

    // to find d
    // method : (k * phi + 1) / e = quotient should be 0 ( perfectly divisible)
    double k = 1;
    double d;
    while (true)
    {
      double temp = 1 + (k * phi);
      if (temp % e == 0)
      {
        d = temp / e;
        break;
      }
      else
      {
        k++;
      }
    }
    System.out.println("d = " + d);

    // encryption
    double c = 0;  // cypher text
    double x = Math.pow(m, e);
    c = x % n;
    System.out.println("Encrypted Data: " + c);

    // decryption
    BigDecimal pt;      // plain text
    double y = Math.pow(c, d);
    BigDecimal Y = BigDecimal.valueOf(y);
    BigDecimal N = BigDecimal.valueOf(n);
    pt = Y.remainder(N);
    System.out.println("Decrypted Data: " + pt);
  }
}

p = 11

q = 5

m = 9

手工计算得出的值:

n = 55

phi = 40

d = 27

加密文本= 14.0

这些是正确的值。

但是即使公式正确,我的解密值也仍然错误。

解密的文本= 25.0 //错误的值。应该是9。

首先,我认为double在计算纯文本时不足以表示较大的值。

所以我用了BigDecimal(我是新手)

用于计算解密文本的公式是正确的。我不明白程序有什么问题。

1 个答案:

答案 0 :(得分:0)

我认为您忘记做.mod(N)而不是.remainder()。

// decryption
BigInteger N = BigDecimal.valueOf(n).toBigInteger();
//converting double value of c to BigInteger
BigInteger C = BigDecimal.valueOf(c).toBigInteger();
int dint = (int) Math.round(d);
BigInteger msgback = (C.pow(dint)).mod(N);
System.out.println("Decrypted Data: " + msgback);

这是一个稍作修改的版本,我将double d转换为整数,因此可以调用pow。祝你好运!