.NET скрывает криптографию платформы — CNG в Windows, OpenSSL в Linux, библиотеки Apple в macOS — за единым API: ECDsa, RSA, MLDsa, MLKem и другими классами. Проверка выполнялась на .NET 10.0.13 в Ubuntu 24.04, где под ним работает OpenSSL 3.0.13, и эта версия определяет ряд результатов.
Кодировка подписи по умолчанию противоположна той, что принята в большинстве серверных библиотек. ECDsa.SignData возвращает 64-байтовую подпись IEEE P1363 r‖s, и VerifyData ожидает именно её; для DER в обоих вызовах нужен DSASignatureFormat.Rfc3279DerSequence. Поэтому .NET без дополнительных настроек совместим с JWS и WebCrypto, но не с OpenSSL, SHA256withECDSA в Java и SignASN1 в Go. На любую некорректную или неподходящую подпись VerifyData возвращает false, поэтому подпись в DER, проверенная с форматом по умолчанию, выглядит точно так же, как подделка; пример показывает оба исхода, а конвертер DER ⇄ raw показывает, какая форма у вас.
В Linux ECDSA работал на кривых от P-256 до P-521, secp256k1 и Brainpool r1, во всех случаях через OpenSSL. SignHash подписывает вычисленный вами дайджест, nonce случайные, s не нормализуется, а проверка принимает high-S. В библиотеке базовых классов нет классов для Ed25519 и Ed448; для EdDSA нужен Bouncy Castle для .NET или другой пакет.
MLKem, MLDsa, SlhDsa и CompositeMLDsa есть в .NET 10, но значение IsSupported у каждого из них зависит от платформы. С OpenSSL 3.0.13 у всех было false; ML-KEM и ML-DSA появились в OpenSSL 3.5, поэтому в Linux для них нужен дистрибутив с этой версией, а в Windows — соответствующая поддержка в CNG. Код должен проверять IsSupported, а не рассчитывать на поддержку заранее; ни одной платформы, где ответ равен true, эта страница не проверяла.
Ключи импортируются из SPKI и PKCS#8 (PEM или DER, с шифрованием или без), SEC1 EC PRIVATE KEY и координат в формате raw в ECParameters; импорта из точки SEC1 или JWK нет. Разобрать файлы PFX поможет инспектор PFX.