错误信息
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`,以及包含 EC 密钥的 `PUBLIC KEY`),`RSA` 对象只接受 RSA 标签。如果标签符合,但其中的密钥属于另一种算法,错误则会变为“Key is not a valid public or private key.”。
原因
传入的是文件路径而不是文件内容
常见`ImportFromPem("/keys/private.pem")` 会在路径字符串中查找 PEM 封装,结果什么也找不到——消息中的提示正是针对这种错误的。
把 RSA PEM 导入 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.
把文件内容传给对应算法的对象
读取文件,创建与密钥算法对应的对象;对于加密的密钥,使用对应的加密版本方法。
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();