Не удалось загрузить открытый ключ RSA

Я пытаюсь прочитать открытый ключ RSA, показанный ниже, но получаю исключение в строке 6: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: ошибка синтаксического анализа algid, а не последовательность

Мой код:

String rsaPublicKey = rsaPublicKeyString.replace(
    "-----BEGIN RSA PUBLIC KEY-----\n", "");
rsaPublicKey = rsaPublicKey.replace("\n-----END RSA PUBLIC KEY-----", "");
byte[] bytes = EncryptionUtils.decodeBase64(rsaPublicKey);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
pubKey = (RSAPublicKey)keyFactory.generatePublic(keySpec);

Открытый ключ RSA:

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6
lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS
an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw
Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+
8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n
Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
-----END RSA PUBLIC KEY-----

Что я делаю неправильно?

ОБНОВЛЕНИЕ:

public static byte[] decodeBase64(String data) throws EncryptionException {
    try {
        BASE64Decoder decoder = new BASE64Decoder();
        return decoder.decodeBuffer(data);
    } catch (Exception e) {
        throw new EncryptionException(e);
    }
}

person afterwhy    schedule 23.07.2013    source источник


Ответы (2)


Проблема вызвана тем, что ваш открытый ключ - это объект RSAPublicKey, а не объект SubjectPublicKeyInfo (см. этот ответ для хорошего описания различия). Вам нужно будет преобразовать один в другой, прежде чем ваш код будет работать.

BouncyCastle может сделать преобразование за вас. Следующий фрагмент кода будет работать, хотя мне он не нравится по двум причинам:

  1. Он использует устаревший класс PEMReader.

  2. Для этого требуется, чтобы был загружен провайдер BouncyCastle.

Код:

Security.addProvider(new BouncyCastleProvider());    
PEMReader reader = new PEMReader(new StringReader(rsaPublicKeyString));    
BCRSAPublicKey key = (BCRSAPublicKey) reader.readObject();
bytes[] = key.getEncoded(); // now in SubjectPublicKeyInfo format.

// as before...

С BouncyCastle всегда есть много способов снять шкуру с кошки. Может быть, кто-нибудь найдет более элегантное решение, чем приведенное выше?

person Duncan Jones    schedule 24.07.2013

Для меня в открытом ключе отсутствовал OID. Мне пришлось исправить это на стороне iOS с помощью справки отсюда: http://blog.wingsofhermes.org/?p=42

Кроме того, мой открытый ключ не нужно было преобразовывать в RSAPublicKey, стандарт работал нормально:

X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
person mikeho    schedule 19.05.2014