Сообщение об ошибке
KeyRejected("InvalidEncoding")
Также выводится как
- KeyRejected("WrongAlgorithm")
- called `Result::unwrap()` on an `Err` value: KeyRejected("InvalidEncoding")
Строка причины бывает разной: `InvalidEncoding`, `WrongAlgorithm`, `InconsistentComponents`, `TooSmall`… `Display` выводит только причину, например `InvalidEncoding`.
ring (Rust crate) — ring::error::KeyRejected from EcdsaKeyPair::from_pkcs8 / Ed25519KeyPair::from_pkcs8
Что это означает
ring отклонил байты закрытого ключа. Для каждого типа ключа ring принимает ровно одну кодировку: для ECDSA и Ed25519 — PKCS#8 (v1 или v2) в DER, для RSA — ещё и PKCS#1 в DER через `from_der`. Причину он сообщает лишь кратко: `InvalidEncoding`, если байты не имеют этой структуры, и `WrongAlgorithm`, если это корректный документ PKCS#8, но для другого алгоритма или кривой. ring никогда не разбирает PEM самостоятельно.
Почему это происходит
Текст PEM передан как байты
часто`include_bytes!("key.pem")` и `fs::read("key.pem")` дают текст PEM. Для ring нужны байты DER, то есть декодированное из base64 содержимое этого текста.
SEC 1 или PKCS#1 вместо PKCS#8
частоФайлы `EC PRIVATE KEY` и `RSA PRIVATE KEY` содержат другие структуры. Пары ключей ECDSA и Ed25519 в ring загружаются только из PKCS#8.
Ключ другого алгоритма или кривой
иногдаКлюч P-384, загруженный с алгоритмом подписи для P-256, или ключ ECDSA, переданный в `Ed25519KeyPair`, дают `WrongAlgorithm`.
Как исправить
- 1.
Декодируйте PEM и проверьте его метку
Используйте парсер PEM, требуйте метку `PRIVATE KEY` и передавайте в ring декодированное содержимое.
rust // Cargo.toml: pem = "3" let pem = pem::parse(std::fs::read_to_string("key.pem")?)?; anyhow::ensure!(pem.tag() == "PRIVATE KEY", "expected PKCS#8, got {}", pem.tag()); let key_pair = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, pem.contents(), &rng) .map_err(|e| anyhow::anyhow!("key rejected: {e}"))?; - 2.
Преобразуйте старые файлы ключей в PKCS#8 DER
OpenSSL преобразует закрытые ключи SEC 1 и PKCS#1 в PKCS#8; с `-outform DER` записываются ровно те байты, которые нужны ring.
bash openssl pkcs8 -topk8 -nocrypt -in ec-sec1.pem -outform DER -out key.pk8 # SEC 1 -> PKCS#8 DER