RSA 算法:执行解密时明文无效


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

φ = 40

d = 27

加密文本 = 14.0

这些是正确的值。

但是即使公式正确,我也得到了错误的解密值。

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

首先,我认为双精度不足以在计算纯文本时表示大值。

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

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

我想你忘了做.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);

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

最新更新