Сообщение об ошибке
Error(InvalidKeyFormat)
Также выводится как
- called `Result::unwrap()` on an `Err` value: Error(InvalidKeyFormat)
- InvalidKeyFormat
`{:?}` выводит `Error(InvalidKeyFormat)`, а `{}` — `InvalidKeyFormat`.
jsonwebtoken (Rust crate) — ErrorKind::InvalidKeyFormat from EncodingKey::from_ec_pem / DecodingKey::from_*_pem
Что это означает
PEM, переданный в конструктор `EncodingKey`/`DecodingKey`, имеет не ту структуру, которую принимает этот конструктор. Для закрытых ключей EC `from_ec_pem` требует PKCS#8 (`-----BEGIN PRIVATE KEY-----`) и отклоняет форму SEC 1 (`-----BEGIN EC PRIVATE KEY-----`), которую записывает `openssl ecparam -genkey`; кроме того, каждый из загрузчиков для RSA, EC и Ed25519 отклоняет ключи других семейств.
Почему это происходит
Закрытый ключ EC в форме SEC 1
часто`openssl ecparam -genkey` и многие старые инструменты записывают `EC PRIVATE KEY`. Загрузчик ключей EC в этом крейте ожидает PKCS#8.
Загрузчик для другого семейства ключей
частоКлюч EC передан в `from_rsa_pem`, ключ RSA — в `from_ec_pem` или ключ Ed25519 — в любую из этих функций. Выбирайте загрузчик по алгоритму ключа.
Вообще не PEM
иногдаJSON-строка JWK, DER-файл, сертификат там, где ожидается ключ, или PEM из конфигурации с экранированными `\n`.
Как исправить
- 1.
Преобразуйте закрытый ключ в PKCS#8
Одна команда OpenSSL преобразует закрытые ключи SEC 1 или PKCS#1 в PKCS#8, который читает любая современная библиотека.
bash # SEC 1 ("EC PRIVATE KEY") or PKCS#1 ("RSA PRIVATE KEY") -> PKCS#8 ("PRIVATE KEY") openssl pkcs8 -topk8 -nocrypt -in ec-sec1.pem -out ec-pkcs8.pem - 2.
Используйте загрузчик, подходящий к ключу
У каждого семейства алгоритмов свой конструктор; для JWK используйте `DecodingKey::from_jwk`.
rust let encoding = EncodingKey::from_ec_pem(&std::fs::read("ec-pkcs8.pem")?)?; // ES256/ES384 let decoding = DecodingKey::from_ec_pem(&std::fs::read("ec-public.pem")?)?; // "PUBLIC KEY" let rsa = DecodingKey::from_rsa_pem(&std::fs::read("rsa-public.pem")?)?; // RS*/PS* let ed = DecodingKey::from_ed_pem(&std::fs::read("ed25519-public.pem")?)?; // EdDSA