Сообщение об ошибке
No supported key formats were found. Check that the input represents the contents of a PEM-encoded key file, not the path to such a file. (Parameter 'input')
Также выводится как
- An encrypted key was found, but no password was provided. Use ImportFromEncryptedPem to import this key. (Parameter 'input')
- Key is not a valid public or private key.
Блок `ENCRYPTED PRIVATE KEY` даёт ошибку «An encrypted key was found, but no password was provided. Use ImportFromEncryptedPem to import this key.»
.NET System.Security.Cryptography — ArgumentException from AsymmetricAlgorithm.ImportFromPem
Что это означает
`ImportFromPem` искал в строке блок PEM с меткой, которую можно импортировать в объект этого алгоритма, и не нашёл ни одного. Метод принимает текст PEM, а не имя файла, причём объект `ECDsa` принимает только метки EC (`PRIVATE KEY`, `EC PRIVATE KEY`, `PUBLIC KEY` с ключом EC), а объект `RSA` — только метки RSA. Если метка подходит, но ключ внутри относится к другому алгоритму, ошибка будет другой: «Key is not a valid public or private key.»
Почему это происходит
Путь к файлу вместо его содержимого
часто`ImportFromPem("/keys/private.pem")` ищет обрамление PEM в строке пути и не находит его — подсказка в сообщении предназначена именно для этой ошибки.
PEM с ключом RSA импортируется в ECDsa (или наоборот)
часто`ECDsa.ImportFromPem` пропускает блоки `RSA PRIVATE KEY` / `RSA PUBLIC KEY`, а `RSA.ImportFromPem` — блоки `EC PRIVATE KEY`.
Сертификат или неподдерживаемый блок
иногдаБлоки `CERTIFICATE`, `CERTIFICATE REQUEST` и `OPENSSH PRIVATE KEY` не относятся к форматам ключей, которые читает `ImportFromPem`.
Ключ зашифрован
иногдаДля зашифрованного PKCS#8 нужен `ImportFromEncryptedPem` с паролем.
Как исправить
- 1.
Передайте содержимое файла объекту нужного алгоритма
Прочитайте файл, создайте объект того алгоритма, к которому относится ключ, а для зашифрованных ключей используйте вариант метода для зашифрованного PEM.
csharp using var ecdsa = ECDsa.Create(); ecdsa.ImportFromPem(File.ReadAllText("/run/secrets/jwt-signing-key.pem")); // contents, not the path // encrypted PKCS#8: ecdsa.ImportFromEncryptedPem(File.ReadAllText(path), Environment.GetEnvironmentVariable("KEY_PASSPHRASE")); - 2.
Загружайте сертификаты как сертификаты
Берите открытый ключ из `X509Certificate2`, а не импортируйте PEM сертификата как ключ.
csharp // .NET 9+: certificates are loaded with X509CertificateLoader, then the key is taken from them var cert = X509CertificateLoader.LoadCertificate(File.ReadAllBytes("cert.der")); using ECDsa? publicKey = cert.GetECDsaPublicKey();