我有完成RSA算法的任务,我在Cormen的书中读到了它并从那里获得了大部分信息。在我遇到大p
和q
素数之前,我认为它很有效。对于大约250和更低的数字加密和解密工作良好,但如果它们更大,模块化指数返回负数,这是没有意义的。
我知道加密号码不能大于n
。我读到我也可以通过使用扩展GCD算法并将x
作为该值来计算逆模,但是当我尝试调用extendedEuclid(phi, e)[1]
时,它返回的值不同于RSA类中的函数。我该如何解决?
以下是计算密钥所需的所有组件的代码。
欧几里德算法
public class Euclid {
public static int euclid(int a, int b) {
if (a < b) {
int tmp = a;
a = b;
b = tmp;
}
if (b == 0) {
return a;
} else {
return euclid(b, a % b);
}
}
public static int[] extendedEuclid(int a, int b) {
if (a < b) {
int tmp = a;
a = b;
b = tmp;
}
if (b == 0) {
return new int[]{a, 1, 0};
} else {
int vals[] = extendedEuclid(b, a % b);
int d = vals[0];
int x = vals[2];
int y = vals[1] - (int) Math.floor(a / b) * vals[2];
return new int[]{d, x, y};
}
}
}
模块化指数
public class Modular {
public static int modularExponentation(int a, int b, int n) {
int c = 0;
int d = 1;
String binaryString = Integer.toBinaryString(b);
for (int i = 0; i < binaryString.length(); i++) {
c = 2 * c;
d = (d * d) % n;
if (binaryString.charAt(i) == '1') {
c = c + 1;
d = (d * a) % n;
}
}
return d;
}
}
RSA生成器
public class RsaKeyGenerator {
int d;
int e;
int n;
public RsaKeyGenerator() {
int p = 827;
int q = 907;
n = p * q;
int phi = (p - 1) * (q - 1);
e = computeCoPrime(phi);
d = invMod(e, phi);
System.out.println("Public: " + e);
System.out.println("Private: " + d);
}
private static int computeCoPrime(int phi) {
int e = 2;
while (Euclid.euclid(e, phi) != 1) {
e++;
}
return e;
}
private int invMod(int a, int n) {
int a0, n0, p0, p1, q, r, t;
p0 = 0;
p1 = 1;
a0 = a;
n0 = n;
q = n0 / a0;
r = n0 % a0;
while (r > 0) {
t = p0 - q * p1;
if (t >= 0) {
t = t % n;
} else {
t = n - ((-t) % n);
}
p0 = p1;
p1 = t;
n0 = a0;
a0 = r;
q = n0 / a0;
r = n0 % a0;
}
return p1;
}
public int encrypt(int num) {
return Modular.modularExponentation(num, e, n);
}
public int decrypt(int cipher) {
return Modular.modularExponentation(cipher, d, n);
}
public static void main(String[] args) {
RsaKeyGenerator rsa = new RsaKeyGenerator();
int cip = rsa.encrypt(1343);
System.out.println(cip);
System.out.println(rsa.decrypt(cip));
}
}
答案 0 :(得分:4)
你面临的问题是整数溢出,所以如果你试图在有符号整数中存储一个高于2 ^ 31 -1的数字,那是不可能的。因此,当你达到这个限制时最终会发生的事情就是数字会回绕到-2 ^ 31 -1。
你想要做的是查看BigInteger类,它可以存储更大的数字并且应该可以正常工作。
整数溢出发生在ModularExponentiation类的这一行:
d = (d * a) % n;