【问题标题】:RSAPrivateKey returns RuntimeExceptionRSAPrivateKey 返回 RuntimeException
【发布时间】:2016-10-26 11:24:52
【问题描述】:

我正在尝试在 Android 上获取 OpenSSLRSAPublicKey 和 OPENSSLRSAPrivateKey 格式的 RSA 密钥。

键看起来像这样(自动生成,不起作用):

私钥字符串: MIICWwIBAAKBgHfvJ1jB80KZTaEYClqbM0znYlos0qTenOF+BSjC4DT31rCwLgMJ 5/c7jSUuzH34OypP8Z7sGMz4UIXzXRGUKXA0TFXvq3aKNMGa74SCB3AGJmjb4yvT rXpTytfeuJsodJzBmwsCkgfkAYZBH06OJAxNPpqoUMUZHOg61hTHwm9nAgMBAAEC gYBC8L3yYVaITo6won1s8wEgJGmV0TzE/udrSG5SwOppRgeTWNJlqcrKCHgQT92d VcaYKETBIh/5j4NKMHo6zIqPpH7GxzNuG3Ua+pmi6VOcdFs7O071q6zAt9aLb/Dd rs7gJb5/H2/LuJBbKInKb+c0IUMEQ9AFoAc70q+um4eJmQJBAOxugXf7LFlCrfun TuR5eYVjLBM9pmVRMEYJcp9CH7qtTAKhdHAKgnZ7Sw3gTxtBi+msnm3zXwtzO/cY Xjh+m7UCQQCB3E8xvJWICLpX/11saDUOZsoaC53A7SunptkbAyJ49yE8SVg3O92i kqRBlFho1JL84vDZe10GXwxj6O1XwigrAkAAzfN01A73ksmCxLP5BQzLzmWU/y20 xIz0gA26yv/Oo85RZ/k8dFyzSIId3viF8DgoqGS1nRFiuZanpZaUfKHNAkAuQwDH dCpE+u7/eE6c1wbHqaCn5Kl/WD5sDEldkSFPvKJPasWNb7tGNj1jy2gveEMg6evp XkRGh8fPM+SRle5fAkEAmaQeOnryugbQBVOAj006jEQaidYsF8FNnKSAyxPQlbSC Nee4pL/hKkjqtm5zKgEp8f0dHRhz5vb94EdLnl1DJA==

公钥字符串: MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHfvJ1jB80KZTaEYClqbM0znYlos 0qTenOF+BSjC4DT31rCwLgMJ5/c7jSUuzH34OypP8Z7sGMz4UIXzXRGUKXA0TFXv q3aKNMGa74SCB3AGJmjb4yvTrXpTytfeuJsodJzBmwsCkgfkAYZBH06OJAxNPpqo UMUZHOg61hTHwm9nAgMBAAE=

这是我的代码:

public static RSAPrivateKey getPrivateKeyFromString(String key) throws IOException, GeneralSecurityException {
    String privateKeyPEM = key;
    privateKeyPEM = privateKeyPEM.replace("-----BEGIN PRIVATE KEY-----\n", "");
    privateKeyPEM = privateKeyPEM.replace("-----END PRIVATE KEY-----", "");
    byte[] encoded = Base64.decode(privateKeyPEM, Base64.DEFAULT);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    ///////// Line below is (RSA.java:37)
    RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(new PKCS8EncodedKeySpec(encoded));
    return privKey;
}
public static RSAPublicKey getPublicKeyFromString(String key) throws IOException, GeneralSecurityException {
    String publicKeyPEM = key;
    publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----\n", "");
    publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
    byte[] encoded = Base64.decode(publicKeyPEM, Base64.DEFAULT);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded));
    return pubKey;
}

有趣的是 pubKey 会返回这个:

OpenSSLRSAPublicKey{modulus=9920c2.....,publicExponent=10001}

但是 privKey 给了我这个例外:

W/System.err: java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0c0890ba:ASN.1 encoding routines:asn1_check_tlen:WRONG_TAG
W/System.err:     at com.android.org.conscrypt.OpenSSLKey.getPrivateKey(OpenSSLKey.java:283)
W/System.err:     at com.android.org.conscrypt.OpenSSLRSAKeyFactory.engineGeneratePrivate(OpenSSLRSAKeyFactory.java:64)
W/System.err:     at java.security.KeyFactory.generatePrivate(KeyFactory.java:187)
W/System.err:     at com.vladmarton.educomiit.RSA$override.getPrivateKeyFromString(RSA.java:37)

我浏览了 stackoverflow 很长时间,但没有找到任何可行的解决方案。我需要让它们与 pubKey 的格式完全相同,但无法让私钥正常工作。

【问题讨论】:

  • “但是 privKey 给了我这个例外……” - 试试-----BEGIN RSA PRIVATE KEY----------END RSA PRIVATE KEY-----
  • 试过了,还是一样
  • 您找到解决方案了吗?我也有同样的问题。
  • 其实我没有。问题仅出在私钥上。我们修复了私钥(解释如下)。我认为这是密钥格式的问题。出于某种原因,它不应该以 -----BEGIN RSA PRIVATE KEY---- 开头,而只是 -----BEGIN PRIVATE KEY----- 左右。检查您的钥匙并尝试使用它们。无论如何,如果它对任何人有帮助,Cipher 使用此配置接受了公钥: Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, publickey); .....我猜这取决于密钥格式

标签: java android asynchronous openssl


【解决方案1】:
 public static PublicKey buildPublicKey() {
    try {
        byte[] keyBytes = Base64.decode(publicKey.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(spec);
    } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
        Logger.e(Logger.TAG, e.getMessage());
    }
    return null;
}
 private static PrivateKey buildPrivateKey() {
    String key= privateKey.replace("-----BEGIN RSA PRIVATE KEY-----", "").replace("-----END RSA PRIVATE KEY-----", "")
            .replaceAll("\\s+", "").replaceAll("\\r+", "").replaceAll("\\n+", "");
    try {
        byte[] keyByteArray = Base64.decode(key, Base64.DEFAULT);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyByteArray);
        return kf.generatePrivate(keySpec);
    } catch (Exception e) {
        Logger.e(Logger.TAG, e.getMessage());
    }
    return null;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-31
    • 2017-07-07
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多