Я пытаюсь разобрать ключ 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 байтов.