java.security.InvalidKeyException:生成 RSA 公钥时的密钥格式无效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25622894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:49:06  来源:igfitidea点击:

java.security.InvalidKeyException: invalid key format on generating RSA public key

javarsapublic-key-encryptionx509public-key

提问by user3619997

Background:

背景:

I have created an applet to extract public key of a certificate extracted from a smart card. This public key is then stored in database. The private key of certificate is used to sign data and the public key is then used to verify the signature. Code for extracting public key from certificate:

我创建了一个小程序来提取从智能卡中提取的证书的公钥。然后将该公钥存储在数据库中。证书的私钥用于对数据进行签名,然后使用公钥来验证签名。从证书中提取公钥的代码:

private byte[] getPublicKey(KeyStore paramKeyStore)
    throws GeneralSecurityException {
  Enumeration localEnumeration = paramKeyStore.aliases();

  if (localEnumeration.hasMoreElements()) {
    String element = (String) localEnumeration.nextElement();
    Certificate[] arrayOfCertificate =
        paramKeyStore.getCertificateChain(element);
    byte[] publicKeyByteArray =
        arrayOfCertificate[0].getPublicKey().getEncoded();

    return publicKeyByteArray;
  }
  throw new KeyStoreException("The keystore is empty!");
}

This publicKeyByteArray is then storeed in database as BLOB after converting to string using bytes2String method:

在使用 bytes2String 方法转换为字符串后,此 publicKeyByteArray 然后作为 BLOB 存储在数据库中:

private static String bytes2String(byte[] bytes) {
  StringBuilder string = new StringBuilder();
  for (byte b : bytes) {
    String hexString = Integer.toHexString(0x00FF & b);
    string.append(hexString.length() == 1 ? "0" + hexString : hexString);
  }
  return string.toString();
}

The content of the BLOB(key) saved in database is:

数据库中保存的BLOB(key)内容为:

30820122300d06092a864886f70d01010105000382010f003082010a02820101009bd307e4fc38adae43b93ba1152a4d6dbf82689336bb4e3af5160d16bf1599fe070f7acbfefd93e866e52043de1620bd57d9a3f244fb4e6ef758d70d19e0be86e1b12595af748fbc00aad9009bd61120d3348079b00af8462de46e254f6d2b092cbc85c7f6194c6c37f8955ef7b9b8937a7e9999541dbbea8c1b2349c712565482dbd573cd9b7ec56a59e7683b4c246620cf0d8148ed38da937f1e4e930eb05d5b4c6054712928fa59870763468c07e71265525e1e40839b51c833579f5742d3c8e0588766e3ed6deef1593b10baad0a2abea34734de1505d37710e1cfaa4225b562b96a6a4e87fecb1d627d4c61916e543eba87054ee9212e8183125cdb49750203010001

After reading the stored public key byte[] from database, I try to convert it back to Public Key using following code:

从数据库读取存储的公钥字节 [] 后,我尝试使用以下代码将其转换回公钥:

Cipher rsa;
rsa = Cipher.getInstance("RSA");
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(pkey.getBytes());
PublicKey pk = keyFactory.generatePublic(publicKeySpec);
rsa.init(Cipher.DECRYPT_MODE, pk);
byte[] cipherDecrypt = rsa.doFinal(encryptedText.getBytes());

but it gives following error:

但它给出了以下错误:

Caused by: java.security.InvalidKeyException: invalid key format
    at sun.security.x509.X509Key.decode(X509Key.java:387)
    at sun.security.x509.X509Key.decode(X509Key.java:403)
    at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:83)
    at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298)
    at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201)

Please suggest the reason and resolution for this issue.

请提出此问题的原因和解决方案。

采纳答案by Duncan Jones

You must have an error in the way you read the key back from the database. The following code works just fine for me:

您从数据库读回密钥的方式一定有错误。以下代码对我来说很好用:

String key = "3082012230..."; // full key omitted for brevity
byte[] derPublicKey = DatatypeConverter.parseHexBinary(key);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(derPublicKey);
keyFactory.generatePublic(publicKeySpec);

I would guess, based on the use of pkey.getBytes(), that you've simply tried to get the bytes from the string rather than hex-decoding it.

我猜,基于 的使用pkey.getBytes(),您只是尝试从字符串中获取字节,而不是对其进行十六进制解码。