java - 错误 :0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag when importing RSA public key

标签 java android encryption

我已经生成了一对 RSA key (公钥和私钥)。现在出于测试目的,我试图将 String 表示中的公钥导入 PublicKey 以在 Android 项目中使用它,以便将 RSA 中的加密消息发送到一个远程服务器,随后将使用私钥对其进行解密。

public static String encryptDataRSA(final String data) throws IOException {  
  final byte[] dataToEncrypt = data.getBytes();
  byte[] encryptedData = null;  

  try {
    final String keyStr = "-----BEGIN PUBLIC KEY-----\n" +
                            "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdQudusozLmogBfU2LCO+WcM59\n" +
                            "ycup9SxMsBNCku23PxrPMO6u//QjtWPz7istE9vkQfa6tQn1Or+SDxeHLMxEesF0\n" +
                            "xiBEgFUhg7vjOF2SnFQQEADgUyizUIBBn1UgKNA8eP24Ux0P0M2aHMn78HIHsRcu\n" +
                            "pNGUNW7p51HOVoIPJQIDAQAB\n" +
                            "-----END PUBLIC KEY-----";

    PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyStr.getBytes()));

    final Cipher cipher = Cipher.getInstance("RSA");  
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
    encryptedData = cipher.doFinal(dataToEncrypt); 

    try {
      final String encryptedText = new String(Base64.encode(encryptedData, Base64.DEFAULT), "UTF-8");
      return encryptedText.toString();
    } 
    catch (final UnsupportedEncodingException e1) { return null; }      
  } catch (Exception e) { e.printStackTrace(); }     

  return "ERROR";
}

问题是这会返回以下异常:

03-19 21:14:31.449: W/System.err(2713): java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
03-19 21:14:31.480: W/System.err(2713):     at org.apache.harmony.xnet.provider.jsse.OpenSSLKey.getPublicKey(OpenSSLKey.java:89)
03-19 21:14:31.480: W/System.err(2713):     at org.apache.harmony.xnet.provider.jsse.OpenSSLRSAKeyFactory.engineGeneratePublic(OpenSSLRSAKeyFactory.java:47)
03-19 21:14:31.489: W/System.err(2713):     at java.security.KeyFactory.generatePublic(KeyFactory.java:171)
03-19 21:14:31.489: W/System.err(2713):     at com.mydomain.myproject.SecurityTools.encryptDataRSA(SecurityTools.java:85)
03-19 21:14:31.501: W/System.err(2713):     at com.mydomain.myproject.MainActivity.onCreate(MainActivity.java:93)
03-19 21:14:31.501: W/System.err(2713):     at android.app.Activity.performCreate(Activity.java:5133)
03-19 21:14:31.509: W/System.err(2713):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
03-19 21:14:31.521: W/System.err(2713):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
03-19 21:14:31.521: W/System.err(2713):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
03-19 21:14:31.529: W/System.err(2713):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
03-19 21:14:31.529: W/System.err(2713):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
03-19 21:14:31.541: W/System.err(2713):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-19 21:14:31.541: W/System.err(2713):     at android.os.Looper.loop(Looper.java:137)
03-19 21:14:31.561: W/System.err(2713):     at android.app.ActivityThread.main(ActivityThread.java:5103)
03-19 21:14:31.571: W/System.err(2713):     at java.lang.reflect.Method.invokeNative(Native Method)
03-19 21:14:31.581: W/System.err(2713):     at java.lang.reflect.Method.invoke(Method.java:525)
03-19 21:14:31.592: W/System.err(2713):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
03-19 21:14:31.601: W/System.err(2713):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-19 21:14:31.609: W/System.err(2713):     at dalvik.system.NativeStart.main(Native Method)
03-19 21:14:31.621: W/System.err(2713): Caused by: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
03-19 21:14:31.649: W/System.err(2713):     at org.apache.harmony.xnet.provider.jsse.NativeCrypto.d2i_PUBKEY(Native Method)
03-19 21:14:31.649: W/System.err(2713):     at org.apache.harmony.xnet.provider.jsse.OpenSSLKey.getPublicKey(OpenSSLKey.java:87)
03-19 21:14:31.663: W/System.err(2713):     ... 18 more

异常指向这一行:cipher.init(Cipher.ENCRYPT_MODE, publicKey);

为什么会返回这个异常,如何解决?谢谢。

最佳答案

X509EncodedKeySpec 需要 DER 编码数据,而不是 PEM 编码数据。如果您简单地丢弃“BEGIN”和“END”并对公钥内容进行 base64 解码,您的代码将正常工作。

final String key2 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdQudusozLmogBfU2LCO+WcM59"
    + "ycup9SxMsBNCku23PxrPMO6u//QjtWPz7istE9vkQfa6tQn1Or+SDxeHLMxEesF0"
    + "xiBEgFUhg7vjOF2SnFQQEADgUyizUIBBn1UgKNA8eP24Ux0P0M2aHMn78HIHsRcu"
    + "pNGUNW7p51HOVoIPJQIDAQAB";

PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(
    new X509EncodedKeySpec(DatatypeConverter.parseBase64Binary(key2)));

关于java - 错误 :0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag when importing RSA public key,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22518608/

相关文章:

安卓标题按钮

javascript - CryptoJS javascript AES-128,欧洲央行加密/解密

linux - 同一服务器上的两个 OwnCloud 实例

java - 如何计算运行时选择的类型 "object"

java - 使用 SHA-256 获取字符串后结果错误

android - 调试失败的 Ant 构建

ubuntu - 将ffmpeg的输出重定向到openssl

java - 为什么 c += 5 编译而不是 c = c + 5?

java - OpenGL:除以 w 零

java - 如何在 android 中使用 Log.d 设置断点