RSA подписать с Java API и проверить с Biginteger - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть класс 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, его точно такие же байты и та же пара ключей.

...