.NET envuelve la criptografía de la plataforma —CNG en Windows, OpenSSL en Linux, las bibliotecas de Apple en macOS— tras una única API: ECDsa, RSA, MLDsa, MLKem y compañía. La comprobación ejecutó .NET 10.0.13 en Ubuntu 24.04, donde el OpenSSL subyacente es el 3.0.13, y esa versión condiciona varios resultados.
La codificación de firma predeterminada es la opuesta a la de la mayoría de las bibliotecas del lado del servidor. ECDsa.SignData devuelve el r‖s IEEE P1363 de 64 bytes y VerifyData lo espera; DER requiere DSASignatureFormat.Rfc3279DerSequence en ambas llamadas. Así, .NET coincide de serie con JWS y WebCrypto, pero no con OpenSSL, ni con SHA256withECDSA de Java ni con SignASN1 de Go. Cualquier firma mal formada o que no corresponda hace que VerifyData devuelva false, así que una firma DER comprobada con el formato predeterminado parece exactamente una falsificación: el ejemplo muestra ambos resultados, y el conversor DER ⇄ en bruto muestra cuál de las dos formas tienes.
En Linux, ECDSA abarcó de P-256 a P-521, secp256k1 y las curvas Brainpool r1, todo a través de OpenSSL. SignHash firma un resumen que calculas tú, los nonces son aleatorios, s no se normaliza y la verificación acepta high-S. No hay ninguna clase Ed25519 ni Ed448 en la biblioteca de clases base; para EdDSA hace falta Bouncy Castle para .NET u otro paquete.
MLKem, MLDsa, SlhDsa y CompositeMLDsa existen en .NET 10, pero cada una informa IsSupported según la plataforma. Con OpenSSL 3.0.13 todas daban false; OpenSSL añadió ML-KEM y ML-DSA en la 3.5, así que en Linux necesitan una distribución que la incluya, y en Windows, la compatibilidad correspondiente de CNG. El código debe comprobar IsSupported en lugar de darlo por hecho, y esta página no ha verificado ninguna plataforma en la que la respuesta sea true.
Las claves se importan desde SPKI y PKCS#8 (PEM o DER, cifrados o no), SEC1 EC PRIVATE KEY y coordenadas en bruto de ECParameters; no hay importación de puntos SEC1 ni de JWK. Inspecciona archivos PFX con el inspector de PFX.