📄 rsacipher.java
字号:
package rsa;
//RSAPrivateKey: RSA private key
import java.math.BigInteger;
import java.security.SecureRandom;
public class RSACipher {
private final BigInteger TWO = new BigInteger("2");
private final BigInteger THREE = new BigInteger("3");
public BigInteger n; // public modulus
public BigInteger e = new BigInteger("3"); // encryption exponent, public key
private BigInteger d; // decryption exponent
private BigInteger p; // first prime
private BigInteger q; // second prime
BigInteger phiN; // (p-1)*(q-1)
public String userName; // attach name to each public/private key pair
public RSACipher(int size) {
generateKeyPair(size);
}
public RSACipher(int size, String name) {
userName = name;
generateKeyPair(size);
}
/**
* Generate the prime pair: (p, q) and key pair (e, d)
*
* @param size
* @param rnd
*/
public void generateKeyPair(int size) { // size = n in bits
// want sizes of primes close, but not too close. Here 10-20 bits apart.
// Random rnd = new Random();
SecureRandom rnd = new SecureRandom();
int size1 = size / 2;
int size2 = size1;
int offset1 = (int) (5.0 * (rnd.nextDouble()) + 5.0);
int offset2 = -offset1;
if (rnd.nextDouble() < 0.5) {
offset1 = -offset1;
offset2 = -offset2;
}
size1 += offset1;
size2 += offset2;
// generate two random primes, so that p*q = n has size bits
BigInteger p1 = new BigInteger(size1, rnd); // random int
p = nextPrime(p1);
BigInteger pM1 = p.subtract(BigInteger.ONE);
BigInteger q1 = new BigInteger(size2, rnd);
q = nextPrime(q1);
BigInteger qM1 = q.subtract(BigInteger.ONE);
n = p.multiply(q);
phiN = pM1.multiply(qM1); // (p-1)*(q-1)
// generate private key. loop conditions:
// 1.the greatest common divisor of privateKey and phi0 is not 1
// 2.privateKey is greater than modulus=p1*p2
// 3.privateKey is less than max{p1, p2}
/**
* Too slow, so abandon this method
*/
// do {
// d = BigInteger.probablePrime(size / 2, rnd);
// } while (d.gcd(phiN).intValue() != 1 || d.compareTo(n) != -1
// || d.compareTo(p.max(q)) == -1);
d = this.e.modInverse(phiN);
}
/**
* nextPrime: next prime p after x, with p-1 and 3 relatively prime
*/
public BigInteger nextPrime(BigInteger x) {
if ((x.remainder(TWO)).equals(BigInteger.ZERO))
x = x.add(BigInteger.ONE);
while (true) {
BigInteger xM1 = x.subtract(BigInteger.ONE);
if (!(xM1.remainder(THREE)).equals(BigInteger.ZERO))
if (x.isProbablePrime(10))
break;
x = x.add(TWO);
}
return x;
}
/**
* RSADecrypt: decryption function
*/
public BigInteger RSADecrypt(BigInteger c) {
return c.modPow(d, n);
}
/**
* RSASign: Sign using private key (d, n) same as decryption for RSA (since
* it is a symmetric PKC)
*/
public BigInteger RSASign(BigInteger m) {
return m.modPow(d, n);
}
/**
* Function RSAEncrypt: The encryption function is E(m) = me mod n, for any
* message m. just raise m to power e (3) mod n. (e, n) is the public key
*/
public BigInteger RSAEncrypt(BigInteger m) {
return m.modPow(e, n);
}
/**
* Function RSAVerify: same as encryption, since RSA is symmetric
*/
public BigInteger RSAVerify(BigInteger s) {
return s.modPow(e, n);
}
public BigInteger getN() {
return n;
}
public void setN(BigInteger n) {
this.n = n;
}
public String toString() {
String s = "";
s += "public key\t=\t" + e + "\n";
s += "modulus\t=\t" + n + "\n";
return s;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -