Ошибка синтаксического анализа Алгида, а не последовательность
При попытке прочитать закрытый ключ RSA из файла с помощью метода
public PrivateKey getPrivateKey()
throws NoSuchAlgorithmException,
InvalidKeySpecException, IOException {
final InputStream inputStream = getClass().getClassLoader()
.getResourceAsStream("privatekey");
byte[] privKeyBytes = null;
try {
privKeyBytes = IOUtils.toByteArray(inputStream);
} catch (final IOException exception) {
LOGGER.error("", exception);
IOUtils.closeQuietly(inputStream);
}
LOGGER.debug("privKeyBytes: {}", privKeyBytes);
String BEGIN = "-----BEGIN RSA PRIVATE KEY-----";
String END = "-----END RSA PRIVATE KEY-----";
String str = new String(privKeyBytes);
if (str.contains(BEGIN) && str.contains(END)) {
str = str.substring(BEGIN.length(), str.lastIndexOf(END));
}
KeyFactory fac = KeyFactory.getInstance("RSA");
EncodedKeySpec privKeySpec =
new PKCS8EncodedKeySpec(Base64.decode(str.getBytes()));
return fac.generatePrivate(privKeySpec);
}
Я получаю исключение
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:200) ~[na:1.6.0_23]
at java.security.KeyFactory.generatePrivate(KeyFactory.java:342) ~[na:1.6.0_23]
на вызове fac.generatePrivate(privKeySpec).
Что означает эта ошибка?
Спасибо
Дмитрий
Ответы
Ответ 1
Это означает, что ваш ключ не находится в формате PKCS # 8. Самое простое - это использовать команду openssl pkcs8 -topk8 <...other options...>
для преобразования ключа один раз. В качестве альтернативы вы можете использовать PEMReader
класс облегченного API Bouncycastle.
Ответ 2
У меня была такая же проблема, и формат ключа НЕ был настоящей проблемой.
Все, что я должен был сделать, чтобы избавиться от этого исключения, заключалось в том, чтобы позвонить
java.security.Security.addProvider(
new org.bouncycastle.jce.provider.BouncyCastleProvider()
);
и все работало
Ответ 3
Вы должны создать файл PCKS8 из личного ключа!
private.pem => имя файла личного ключа
openssl genrsa -out private.pem 1024
public_key.pem => имя файла открытого ключа
openssl rsa -in private.pem -pubout -outform PEM -out public_key.pem
private_key.pem => имя закрытого ключа в формате PCKS8! Вы можете просто прочитать этот формат в Java
openssl pkcs8 -topk8 -inform PEM -in private.pem -out private_key.pem -nocrypt
Ответ 4
Для меня у меня отсутствовал OID в открытом ключе. Мне пришлось исправить это на стороне iOS, используя справку отсюда: http://blog.wingsofhermes.org/?p=42
Кроме того, мой открытый ключ не должен был быть отправлен в RSAPublicKey, стандарт работал просто отлично:
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);