实现RSA算法

时间:2014-01-04 12:10:38

标签: java algorithm math encryption cryptography

我有完成RSA算法的任务,我在Cormen的书中读到了它并从那里获得了大部分信息。在我遇到大pq素数之前,我认为它很有效。对于大约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));
    }
}

1 个答案:

答案 0 :(得分:4)

你面临的问题是整数溢出,所以如果你试图在有符号整数中存储一个高于2 ^ 31 -1的数字,那是不可能的。因此,当你达到这个限制时最终会发生的事情就是数字会回绕到-2 ^ 31 -1。

你想要做的是查看BigInteger类,它可以存储更大的数字并且应该可以正常工作。

整数溢出发生在ModularExponentiation类的这一行:

d = (d * a) % n;