У меня есть класс RSA BigInteger, и с помощью этого класса вы можете генерировать ключи, шифровать, расшифровывать, подписывать и проверять данные.
class RSA {
public static RSAKeyPair generateKeyPair(int size) {
Random rnd = new SecureRandom();
BigInteger p = new BigInteger(size / 2, 100, rnd);
BigInteger q = new BigInteger(size / 2, 100, rnd);
BigInteger n = p.multiply(q);
BigInteger phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
BigInteger e;
do {
e = new BigInteger(phi.bitLength(), rnd);
} while (e.compareTo(BigInteger.ONE) <= 0 || e.compareTo(phi) >= 0 || !e.gcd(phi).equals(BigInteger.ONE));
BigInteger d = e.modInverse(phi);
return new RSAKeyPair(new RSAPublicKey(n, e), new RSAPrivateKey(n, d), n);
}
public static BigInteger encrypt(BigInteger m, RSAPublicKey key) {
return m.modPow(key.getPublicExponent(), key.getModulus());
}
public static BigInteger decrypt(BigInteger c, RSAPrivateKey key) {
return c.modPow(key.getPrivateExponent(), key.getModulus());
}
public static BigInteger sign(BigInteger m, RSAPrivateKey key) {
return m.modPow(key.getPrivateExponent(), key.getModulus());
}
public static boolean verify(BigInteger m, BigInteger s, RSAPublicKey key) {
return s.modPow(key.getPublicExponent(), key.getModulus()).equals(m);
}
}
class RSAKeyPair {
private RSAPublicKey pub;
private RSAPrivateKey priv;
private BigInteger n;
public RSAKeyPair(RSAPublicKey pub, RSAPrivateKey priv, BigInteger n) {
this.pub = pub;
this.priv = priv;
this.n = n;
}
public RSAPublicKey getPublicKey() {
return pub;
}
public RSAPrivateKey getPrivateKey() {
return priv;
}
public BigInteger getModulus() {
return n;
}
}
class RSAPublicKey {
private BigInteger n;
private BigInteger e;
public RSAPublicKey(BigInteger n, BigInteger e) {
this.n = n;
this.e = e;
}
public BigInteger getModulus() {
return n;
}
public BigInteger getPublicExponent() {
return e;
}
}
class RSAPrivateKey {
private BigInteger n;
private BigInteger d;
public RSAPrivateKey(BigInteger n, BigInteger d) {
this.n = n;
this.d = d;
}
public BigInteger getModulus() {
return n;
}
public BigInteger getPrivateExponent() {
return d;
}
}
этот класс работает, но у меня возникает проблема: когда я подписываюстрока с Java API и проверить его с классом RSA его возвращаемое значение false.
code:
byte[] data = "poop".getBytes();
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(1024);
KeyPair pair = gen.generateKeyPair();
Signature sig = Signature.getInstance("NONEwithRSA");
sig.initSign(pair.getPrivate());
sig.update(data);
byte[] sign = sig.sign();
java.security.interfaces.RSAPublicKey pub = (java.security.interfaces.RSAPublicKey) pair.getPublic();
BigInteger m = new BigInteger(data);
BigInteger c = new BigInteger(sign);
RSAPublicKey key = new RSAPublicKey(pub.getModulus(), pub.getPublicExponent()); // not the java.security.interfaces.RSAPublicKey rather the RSAPublicKey from my class see above
boolean verify = RSA.verify(m, c, key);
System.out.println(verify);
почему он возвращает false, его точно такие же байты и та же пара ключей.