【发布时间】:2018-02-21 08:47:49
【问题描述】:
作为一名 IT 教师,我想向我的学生展示 RSA 算法的工作原理。我还想向他们展示通过迭代所有可能的素数来“破解”它需要很长时间。
对于
Eg:
p, q are primes
n = p * q
phi = (p-1) * (q -1)
d = (1 + (k * phi)) / e;
**encryption:**
c = (msg ^ e) % n
**decryption**
message = c ^ d % n;
对于 p = 563 和 q = 569,解密工作正常。
另一方面,对于 p = 1009 和 q = 1013,解密后的消息 =/= 原始消息。
我认为错误在于计算私有指数“d”。我用 BigIntegers 替换了所有 int,但这并没有改变任何事情。有人有想法吗?
class RSA
{
private BigInteger primeOne;
private BigInteger primeTwo;
private BigInteger exp;
private BigInteger phi;
private BigInteger n;
private BigInteger d;
private BigInteger k;
private void calculateParameters(){
// First part of public key:
this.n = this.primeOne * this.primeTwo;
// Finding other part of public key.
this.phi = (this.primeOne - 1) * (this.primeTwo - 1);
//Some integer k
this.k = 2;
this.exp = 2;
while (this.exp < (int) this.phi)
{
// e must be co-prime to phi and
// smaller than phi.
if (gcd(exp, phi) == 1)
break;
else
this.exp++;
}
this.d = (BigInteger) (1 + (this.k * this.phi)) / this.exp; ;
}
// Return greatest common divisors
private static BigInteger gcd(BigInteger a, BigInteger b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
//Encryption algorithm RSA
public string Encrypt(string msg)
{
calculateParameters();
BigInteger encryptedNumber = BigInteger.Pow(BigInteger.Parse(msg),(int) this.exp) % this.n;
// Encryption c = (msg ^ e) % n
return Convert.ToString(encryptedNumber);
}
public string Decrypt(string encrypted)
{
BigInteger intAlphaNumber = BigInteger.Parse(encrypted);
BigInteger decryptedAlphaNumber = BigInteger.Pow(intAlphaNumber,(int) this.d) % n;
return Convert.ToString(decryptedAlphaNumber);
}
}
}
【问题讨论】:
-
BigInteger.Parse(msg) 是否符合您的预期?如果消息是字母数字怎么办?
-
你的实现中总是有 k=2。所以简而言之,你计算 d 的启发式方法并不总是有效。
-
在我的原始代码中,我将字母转换为数字,但我保留了它。我只想加密数字 89(=“HI”)。当我用大素数对其进行加密时,数字会被错误地解密。
-
当 n>2^16 时,需要担心 32 位 int 溢出。
-
您可能想单独使用 ModPow 而不是 Pow 和 Mod。它的扩展性要好得多。
标签: c# encryption rsa primes