Как прочитать RSA publi c ключ из файла / строки в java / kotlin, используя BouncyCastle - PullRequest
1 голос
/ 27 января 2020

Я пытаюсь разобрать ключ publi c в формате RSA из kotlin. У меня есть ключ в строке, содержимое которой выглядит следующим образом:

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAwAzOKC8d0o0dcv1KqILLehASGgOWyjlAc+adazix6ThhX7QeD3Qw
HzxPpbwsJrVPIEMEIN383awIqnCfIL+AbCQPL13XaUCCS74wC5a84X1r6hcI5XO1
9CPAn+jBKmTr4hPaHWKxuhfO3PcXxGfQdXyqNT96bCYnAYaeSECohFjqDbe+RFcL
1lIns2GtQPMh1/uDyhPA+8HSguREWn+Ac3I2c0wtrzZa6R4nruPgIi6XbWRqAskr
tzbO2Xy6O1DcERH9tg+es/pbrWHRHrwEmLXorj3iGqkJJBUmLeW6B5EjmIgiukdJ
dw7bLTNcwf2n0BLJy/bgnhcw4TMOzUadSQIDAQAB
-----END RSA PUBLIC KEY-----

Я нашел много примеров кода для этого, которые включают обрезание BEGIN и END с использованием String.replace (), но это казалось мне повезло. Код BouncyCastle, кажется, уже обрабатывает это , включая возможность создания анализаторов для различных типов «файлов», с которыми он сталкивается. Я пытаюсь это:

try {
    val parser = PEMParser(StringReader(publicKeyString))
    val pemObject = parser.readPemObject()
    val pemContent = pemObject.content
    val key = org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(pemContent)
    serviceLogger.info("Key object: {}", key)
} catch (e: Exception) {
    serviceLogger.error("Could not generate key from keyspec", e)
}

Я получаю до pemContent (массив байтов) без проблем, но когда я пытаюсь фактически проанализировать это в RSAPublicKey, я получаю это:

java.lang.IllegalArgumentException: failed to construct sequence from byte[]: DEF length 3 object truncated by 2

Чего я не могу понять, так это того, правильно ли я вызываю RSAPublicKey.getInstance () - с содержимым всего PemObject - или это исключение говорит мне, что с моим ключом что-то не так.

Примеры, которые мне удалось найти по этому поводу, довольно старые, и API-интерфейсы, похоже, эволюционировали до такой степени, что мне не пришлось бы разбирать строки вручную.

Я сомневаюсь, что это действительно помогает, но я генерирую этот файл в go из пары ключей rsa:

func PublicKeyToPemBytes(prvkey *rsa.PrivateKey) ([]byte, error) {
    var pubkey *rsa.PublicKey
    pubkey = &prvkey.PublicKey

    pubkey_bytes := x509.MarshalPKCS1PublicKey(pubkey)
    if pubkey_bytes == nil {
        return nil, errors.New("Public key could not be serialized")
    }

    pubkey_pem := pem.EncodeToMemory(
        &pem.Block{
            Type:  "RSA PUBLIC KEY",
            Bytes: pubkey_bytes,
        },
    )

    return pubkey_pem, nil
}

go rsa.PublicKey объект содержит N и E. Это дает мне файл, подобный перечисленному выше, и декодирование base64 дает точно такую ​​же длину, 270 байтов.

1 Ответ

0 голосов
/ 28 января 2020

dave_thompson_085 был прав. Этот код действительно работает. Он спросил меня, могу ли я изменить данные, что заставило меня более внимательно посмотреть на них, и я понял, что выполняю .toUpperCase () на base64. Результат был все еще совершенно действительным base64 с некоторыми битами, включенными здесь и там. Я не должен был делать это .toUpperCase () вообще, я просто не видел, пока он не сказал это. Надувной работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...