Java:OpenSSLRSAPrivateCrtKey与OpenSSLRSAPrivateKey

Java:OpenSSLRSAPrivateCrtKey与OpenSSLRSAPrivateKey,java,android,rsa,Java,Android,Rsa,当我使用以下代码生成私钥时 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(2048); KeyPair kp = kpg.genKeyPair(); PrivateKey privateKey = kp.getPrivate(); 我得到私有密钥的OpenSSLRSAPrivateCrtKey表示。 然后我将其转换为字节数组,保存,然后使用以下代码还原: byte[] e

当我使用以下代码生成私钥时

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
PrivateKey privateKey = kp.getPrivate();
我得到私有密钥的OpenSSLRSAPrivateCrtKey表示。 然后我将其转换为字节数组,保存,然后使用以下代码还原:

byte[] encodedPrivateKey = null;
fileInputStream = new FileInputStream(file);
encodedPrivateKey = new byte[(int) file.length()];
fileInputStream.read(encodedPrivateKey);
fileInputStream.close();

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
但这次我得到了OpenSSLRSAPrivateKey表示

我想知道
OpenSSLRSAPrivateCrtKey
OpenSSLRSAPrivateKey
之间有什么区别。另外,我应该使用哪种私钥表示来解密此密钥对中由公钥加密的信息?

扩展了

新成员 新构造函数,调用init 初始化重写 起初是这样

private static OpenSSLKey init(RSAPrivateKeySpec rsaKeySpec) throws InvalidKeySpecException {
    final BigInteger modulus = rsaKeySpec.getModulus();
    final BigInteger privateExponent = rsaKeySpec.getPrivateExponent();

    if (modulus == null) {
        throw new InvalidKeySpecException("modulus == null");
    } else if (privateExponent == null) {
        throw new InvalidKeySpecException("privateExponent == null");
    }

    try {
        return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
                modulus.toByteArray(),
                null,
                privateExponent.toByteArray(),
                null,
                null,
                null,
                null,
                null));
    } catch (Exception e) {
        throw new InvalidKeySpecException(e);
    }
}
现在是了

private static OpenSSLKey init(RSAPrivateCrtKeySpec rsaKeySpec) throws InvalidKeySpecException {
    BigInteger modulus = rsaKeySpec.getModulus();
    BigInteger privateExponent = rsaKeySpec.getPrivateExponent();

    if (modulus == null) {
        throw new InvalidKeySpecException("modulus == null");
    } else if (privateExponent == null) {
        throw new InvalidKeySpecException("privateExponent == null");
    }

    try {
        /*
         * OpenSSL uses the public modulus to do RSA blinding. If
         * the public modulus is not available, the call to
         * EVP_PKEY_new_RSA will turn off blinding for this key
         * instance.
         */
        final BigInteger publicExponent = rsaKeySpec.getPublicExponent();
        final BigInteger primeP = rsaKeySpec.getPrimeP();
        final BigInteger primeQ = rsaKeySpec.getPrimeQ();
        final BigInteger primeExponentP = rsaKeySpec.getPrimeExponentP();
        final BigInteger primeExponentQ = rsaKeySpec.getPrimeExponentQ();
        final BigInteger crtCoefficient = rsaKeySpec.getCrtCoefficient();

        return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
                modulus.toByteArray(),
                publicExponent == null ? null : publicExponent.toByteArray(),
                privateExponent.toByteArray(),
                primeP == null ? null : primeP.toByteArray(),
                primeQ == null ? null : primeQ.toByteArray(),
                primeExponentP == null ? null : primeExponentP.toByteArray(),
                primeExponentQ == null ? null : primeExponentQ.toByteArray(),
                crtCoefficient == null ? null : crtCoefficient.toByteArray()));
    } catch (Exception e) {
        throw new InvalidKeySpecException(e);
    }
}
正如我们所看到的,当被实例化时,我们在这两种情况下都传递
NativeCrypto.EVP\u PKEY\u new\u RSA
。OpenSSLRSAPrivateCrtKey通行证:

  • 公众指数
  • 普瑞普
  • primeQ
  • 素数指数
  • 素数指数
  • CRT效率
getInstance 它从

static OpenSSLRSAPrivateKey getInstance(OpenSSLKey key) {
    byte[][] params = NativeCrypto.get_RSA_private_params(key.getNativeRef());
    if (params[1] != null) {
        return new OpenSSLRSAPrivateCrtKey(key, params);
    }
    return new OpenSSLRSAPrivateKey(key, params);
}
void readParams(byte[][] params) {
    if (params[0] == null) {
        throw new NullPointerException("modulus == null");
    } else if (params[2] == null && !key.isHardwareBacked()) {
        throw new NullPointerException("privateExponent == null");
    }

    modulus = new BigInteger(params[0]);

    // ENGINE-based keys are not guaranteed to have a private exponent.
    if (params[2] != null) {
        privateExponent = new BigInteger(params[2]);
    }
}
@Override
public boolean equals(Object o) {
    if (o == this) {
        return true;
    }

    if (o instanceof OpenSSLRSAPrivateKey) {
        OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
        return key.equals(other.getOpenSSLKey());
    }

    if (o instanceof RSAPrivateKey) {
        ensureReadParams();
        RSAPrivateKey other = (RSAPrivateKey) o;

        return modulus.equals(other.getModulus())
                && privateExponent.equals(other.getPrivateExponent());
    }

    return false;
}
@Override
public String toString() {
    final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateKey{");

    ensureReadParams();
    sb.append("modulus=");
    sb.append(modulus.toString(16));

    return sb.toString();
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    stream.defaultReadObject();

    key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
            modulus.toByteArray(),
            null,
            privateExponent.toByteArray(),
            null,
            null,
            null,
            null,
            null));
    fetchedParams = true;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
    if (key.isHardwareBacked()) {
        throw new NotSerializableException("Hardware backed keys can not be serialized");
    }
    ensureReadParams();
    stream.defaultWriteObject();
}

新版本计算

  • 模数
  • 私人指数
如果失败,则会引发一些异常。否则,它将继续计算内容,即:

  • 公众指数
  • 普瑞普
  • primeQ
  • 素数指数
  • 素数指数
  • CRT效率
然后生成一个类似于
init
OpenSSLKey
。我认为这是可以重构的,因为它涉及到一些代码重复,但我的观点没有差异那么重要

readParams 这从

static OpenSSLRSAPrivateKey getInstance(OpenSSLKey key) {
    byte[][] params = NativeCrypto.get_RSA_private_params(key.getNativeRef());
    if (params[1] != null) {
        return new OpenSSLRSAPrivateCrtKey(key, params);
    }
    return new OpenSSLRSAPrivateKey(key, params);
}
void readParams(byte[][] params) {
    if (params[0] == null) {
        throw new NullPointerException("modulus == null");
    } else if (params[2] == null && !key.isHardwareBacked()) {
        throw new NullPointerException("privateExponent == null");
    }

    modulus = new BigInteger(params[0]);

    // ENGINE-based keys are not guaranteed to have a private exponent.
    if (params[2] != null) {
        privateExponent = new BigInteger(params[2]);
    }
}
@Override
public boolean equals(Object o) {
    if (o == this) {
        return true;
    }

    if (o instanceof OpenSSLRSAPrivateKey) {
        OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
        return key.equals(other.getOpenSSLKey());
    }

    if (o instanceof RSAPrivateKey) {
        ensureReadParams();
        RSAPrivateKey other = (RSAPrivateKey) o;

        return modulus.equals(other.getModulus())
                && privateExponent.equals(other.getPrivateExponent());
    }

    return false;
}
@Override
public String toString() {
    final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateKey{");

    ensureReadParams();
    sb.append("modulus=");
    sb.append(modulus.toString(16));

    return sb.toString();
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    stream.defaultReadObject();

    key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
            modulus.toByteArray(),
            null,
            privateExponent.toByteArray(),
            null,
            null,
            null,
            null,
            null));
    fetchedParams = true;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
    if (key.isHardwareBacked()) {
        throw new NotSerializableException("Hardware backed keys can not be serialized");
    }
    ensureReadParams();
    stream.defaultWriteObject();
}

因为新成员

吸气剂 等于 已从

static OpenSSLRSAPrivateKey getInstance(OpenSSLKey key) {
    byte[][] params = NativeCrypto.get_RSA_private_params(key.getNativeRef());
    if (params[1] != null) {
        return new OpenSSLRSAPrivateCrtKey(key, params);
    }
    return new OpenSSLRSAPrivateKey(key, params);
}
void readParams(byte[][] params) {
    if (params[0] == null) {
        throw new NullPointerException("modulus == null");
    } else if (params[2] == null && !key.isHardwareBacked()) {
        throw new NullPointerException("privateExponent == null");
    }

    modulus = new BigInteger(params[0]);

    // ENGINE-based keys are not guaranteed to have a private exponent.
    if (params[2] != null) {
        privateExponent = new BigInteger(params[2]);
    }
}
@Override
public boolean equals(Object o) {
    if (o == this) {
        return true;
    }

    if (o instanceof OpenSSLRSAPrivateKey) {
        OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
        return key.equals(other.getOpenSSLKey());
    }

    if (o instanceof RSAPrivateKey) {
        ensureReadParams();
        RSAPrivateKey other = (RSAPrivateKey) o;

        return modulus.equals(other.getModulus())
                && privateExponent.equals(other.getPrivateExponent());
    }

    return false;
}
@Override
public String toString() {
    final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateKey{");

    ensureReadParams();
    sb.append("modulus=");
    sb.append(modulus.toString(16));

    return sb.toString();
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    stream.defaultReadObject();

    key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
            modulus.toByteArray(),
            null,
            privateExponent.toByteArray(),
            null,
            null,
            null,
            null,
            null));
    fetchedParams = true;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
    if (key.isHardwareBacked()) {
        throw new NotSerializableException("Hardware backed keys can not be serialized");
    }
    ensureReadParams();
    stream.defaultWriteObject();
}

因为新成员

哈希码 如果publicExponent为null,则与基类中的相同。如果不是,则根据基类的哈希代码和publicExponent的哈希代码计算哈希代码,计算两者之间的按位异或

托斯特林 从

static OpenSSLRSAPrivateKey getInstance(OpenSSLKey key) {
    byte[][] params = NativeCrypto.get_RSA_private_params(key.getNativeRef());
    if (params[1] != null) {
        return new OpenSSLRSAPrivateCrtKey(key, params);
    }
    return new OpenSSLRSAPrivateKey(key, params);
}
void readParams(byte[][] params) {
    if (params[0] == null) {
        throw new NullPointerException("modulus == null");
    } else if (params[2] == null && !key.isHardwareBacked()) {
        throw new NullPointerException("privateExponent == null");
    }

    modulus = new BigInteger(params[0]);

    // ENGINE-based keys are not guaranteed to have a private exponent.
    if (params[2] != null) {
        privateExponent = new BigInteger(params[2]);
    }
}
@Override
public boolean equals(Object o) {
    if (o == this) {
        return true;
    }

    if (o instanceof OpenSSLRSAPrivateKey) {
        OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
        return key.equals(other.getOpenSSLKey());
    }

    if (o instanceof RSAPrivateKey) {
        ensureReadParams();
        RSAPrivateKey other = (RSAPrivateKey) o;

        return modulus.equals(other.getModulus())
                && privateExponent.equals(other.getPrivateExponent());
    }

    return false;
}
@Override
public String toString() {
    final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateKey{");

    ensureReadParams();
    sb.append("modulus=");
    sb.append(modulus.toString(16));

    return sb.toString();
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    stream.defaultReadObject();

    key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
            modulus.toByteArray(),
            null,
            privateExponent.toByteArray(),
            null,
            null,
            null,
            null,
            null));
    fetchedParams = true;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
    if (key.isHardwareBacked()) {
        throw new NotSerializableException("Hardware backed keys can not be serialized");
    }
    ensureReadParams();
    stream.defaultWriteObject();
}

readObject 从

static OpenSSLRSAPrivateKey getInstance(OpenSSLKey key) {
    byte[][] params = NativeCrypto.get_RSA_private_params(key.getNativeRef());
    if (params[1] != null) {
        return new OpenSSLRSAPrivateCrtKey(key, params);
    }
    return new OpenSSLRSAPrivateKey(key, params);
}
void readParams(byte[][] params) {
    if (params[0] == null) {
        throw new NullPointerException("modulus == null");
    } else if (params[2] == null && !key.isHardwareBacked()) {
        throw new NullPointerException("privateExponent == null");
    }

    modulus = new BigInteger(params[0]);

    // ENGINE-based keys are not guaranteed to have a private exponent.
    if (params[2] != null) {
        privateExponent = new BigInteger(params[2]);
    }
}
@Override
public boolean equals(Object o) {
    if (o == this) {
        return true;
    }

    if (o instanceof OpenSSLRSAPrivateKey) {
        OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
        return key.equals(other.getOpenSSLKey());
    }

    if (o instanceof RSAPrivateKey) {
        ensureReadParams();
        RSAPrivateKey other = (RSAPrivateKey) o;

        return modulus.equals(other.getModulus())
                && privateExponent.equals(other.getPrivateExponent());
    }

    return false;
}
@Override
public String toString() {
    final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateKey{");

    ensureReadParams();
    sb.append("modulus=");
    sb.append(modulus.toString(16));

    return sb.toString();
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    stream.defaultReadObject();

    key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
            modulus.toByteArray(),
            null,
            privateExponent.toByteArray(),
            null,
            null,
            null,
            null,
            null));
    fetchedParams = true;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
    if (key.isHardwareBacked()) {
        throw new NotSerializableException("Hardware backed keys can not be serialized");
    }
    ensureReadParams();
    stream.defaultWriteObject();
}

写对象 从

static OpenSSLRSAPrivateKey getInstance(OpenSSLKey key) {
    byte[][] params = NativeCrypto.get_RSA_private_params(key.getNativeRef());
    if (params[1] != null) {
        return new OpenSSLRSAPrivateCrtKey(key, params);
    }
    return new OpenSSLRSAPrivateKey(key, params);
}
void readParams(byte[][] params) {
    if (params[0] == null) {
        throw new NullPointerException("modulus == null");
    } else if (params[2] == null && !key.isHardwareBacked()) {
        throw new NullPointerException("privateExponent == null");
    }

    modulus = new BigInteger(params[0]);

    // ENGINE-based keys are not guaranteed to have a private exponent.
    if (params[2] != null) {
        privateExponent = new BigInteger(params[2]);
    }
}
@Override
public boolean equals(Object o) {
    if (o == this) {
        return true;
    }

    if (o instanceof OpenSSLRSAPrivateKey) {
        OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
        return key.equals(other.getOpenSSLKey());
    }

    if (o instanceof RSAPrivateKey) {
        ensureReadParams();
        RSAPrivateKey other = (RSAPrivateKey) o;

        return modulus.equals(other.getModulus())
                && privateExponent.equals(other.getPrivateExponent());
    }

    return false;
}
@Override
public String toString() {
    final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateKey{");

    ensureReadParams();
    sb.append("modulus=");
    sb.append(modulus.toString(16));

    return sb.toString();
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    stream.defaultReadObject();

    key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
            modulus.toByteArray(),
            null,
            privateExponent.toByteArray(),
            null,
            null,
            null,
            null,
            null));
    fetchedParams = true;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
    if (key.isHardwareBacked()) {
        throw new NotSerializableException("Hardware backed keys can not be serialized");
    }
    ensureReadParams();
    stream.defaultWriteObject();
}


你能解决吗?我也有同样的问题。找到解决方案了吗?首先感谢你的全面回答。但我想这并不能真正回答这个问题。我想总结一下如何更好地使用OpenSSLRSAPrivateCrtKey,因为它扩展了旧版本。但我真的看不出改变了什么的好处。我猜Crt意味着证书,因为RSA通常用于签名验证。但在给定的示例中,我们使用它进行加密,使用CrtKey是否会有缺点,因此更好地使用父类?@Hatzen我不知道子类的缺点。子类更复杂,因为它考虑了其他值。