Сообщение об ошибке
System.Security.Cryptography.CryptographicException: ASN1 corrupted data.
Также выводится как
- ASN1 corrupted data.
- Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: ASN1 corrupted data.
В Linux и macOS тип исключения — `CryptographicException`; в Windows оно может появляться как `WindowsCryptographicException` с тем же текстом. Внутреннее исключение выглядит, например, так: «The provided data is tagged with 'Universal' class value '2', but it should have been 'Universal' class value '16'.»
.NET System.Security.Cryptography — ImportSubjectPublicKeyInfo / ImportPkcs8PrivateKey / ImportRSAPrivateKey / ImportECPrivateKey
Что это означает
Байты, которые вы передали в один из методов `Import…`, содержат не ту структуру ASN.1, которую декодирует этот метод. Каждый метод читает ровно одну структуру — PKCS#8, PKCS#1, SEC 1 или SubjectPublicKeyInfo, — и внешний DER ей не соответствует, поэтому .NET сообщает, что данные повреждены, хотя сам ключ в другом формате может быть совершенно исправен. Внутреннее исключение `AsnContentException` указывает на несовпадение тегов.
Почему это происходит
Путаница PKCS#1 и PKCS#8 (или SEC 1)
частоБайты `RSA PRIVATE KEY` переданы в `ImportPkcs8PrivateKey` или байты `PRIVATE KEY` — в `ImportRSAPrivateKey`. Структуры различаются первым элементом (INTEGER или SEQUENCE).
Текст PEM или base64 передан как DER
часто`Encoding.ASCII.GetBytes(pem)` или `Convert.FromBase64String`, применённые ко всему файлу вместе со строками обрамления PEM, не дают DER.
Перепутаны методы для открытого и закрытого ключа
иногдаЗакрытый ключ передан в `ImportSubjectPublicKeyInfo` или сертификат (а не ключ) передан в какой-либо метод импорта ключа.
Как исправить
- 1.
Используйте ImportFromPem для PEM-файлов
Он выбирает декодер по метке PEM, так что не нужно вручную подбирать DER-декодер и рисковать ошибиться. Сертификаты же загружайте через `X509Certificate2`.
csharp // .NET 5+: ImportFromPem reads the label and picks the right decoder // (PRIVATE KEY, RSA PRIVATE KEY, EC PRIVATE KEY, PUBLIC KEY, RSA PUBLIC KEY). using var key = ECDsa.Create(); key.ImportFromPem(File.ReadAllText("key.pem")); - 2.
Выберите метод по структуре DER
Если приходится работать с двоичным DER, выбирайте метод импорта по тому, что содержат данные; просмотрщик ASN.1 покажет, какая у вас структура.
csharp // DER input: choose the method by structure rsa.ImportPkcs8PrivateKey(der, out _); // "PRIVATE KEY" rsa.ImportRSAPrivateKey(der, out _); // "RSA PRIVATE KEY" rsa.ImportSubjectPublicKeyInfo(der, out _); // "PUBLIC KEY" rsa.ImportRSAPublicKey(der, out _); // "RSA PUBLIC KEY" ecdsa.ImportECPrivateKey(der, out _); // "EC PRIVATE KEY"