#:package NSec.Cryptography@26.4.0using System.Text;using NSec.Cryptography; // .NET's System.Security.Cryptography has no Ed25519; NSec wraps libsodiumvar algorithm = SignatureAlgorithm.Ed25519; using var privateKey = Key.Import(algorithm, File.ReadAllBytes("key.pem"), KeyBlobFormat.PkixPrivateKeyText);byte[] message = File.ReadAllBytes("message.txt");byte[] signature = algorithm.Sign(privateKey, message); File.WriteAllBytes("sig.bin", signature);Console.WriteLine($"signature: {Convert.ToHexStringLower(signature)}");var publicKey = PublicKey.Import(algorithm, File.ReadAllBytes("pub.pem"), KeyBlobFormat.PkixPublicKeyText); Console.WriteLine($"valid: {algorithm.Verify(publicKey, message, signature)}");Console.WriteLine($"tampered message valid: {algorithm.Verify(publicKey, Encoding.UTF8.GetBytes("hello ed25520"), signature)}");How it works
#:package NSec.Cryptography@26.4.0letsdotnet run app.csrestore the package without a project file; in a project, add the same version withdotnet add package.Key.Import(algorithm, bytes, KeyBlobFormat.PkixPrivateKeyText)readsBEGIN PRIVATE KEY, andPublicKey.Import(…, KeyBlobFormat.PkixPublicKeyText)readsBEGIN PUBLIC KEY. TheRawPrivateKeyandRawPublicKeyformats take the bare 32 bytes instead.algorithm.Sign(key, message)returns 64 bytes;algorithm.Verify(publicKey, message, signature)returns abool.Keyholds the private key in unmanaged memory — dispose it (using var) when done.
Gotchas
- Do not look for it in the platform: .NET 10 added
MLDsa,SlhDsaandMLKemto System.Security.Cryptography, but no Ed25519 type, andECDsaonly covers Weierstrass curves such as P-256. - Imported keys are not exportable by default:
key.Export(KeyBlobFormat.RawPrivateKey)throwsInvalidOperationException: The key cannot be exported.Passnew KeyCreationParameters { ExportPolicy = KeyExportPolicies.AllowPlaintextExport }toKey.Importwhen you need it. - A PEM of another key type, such as a P-256 key, throws
FormatException: The key BLOB is not in the correct format.;Key.TryImportreturnsfalseinstead. - NSec needs the native libsodium that its NuGet dependency ships for the usual Windows, Linux and macOS targets. Where native code is not an option, BouncyCastle.Cryptography's
Ed25519Signeris the fully managed alternative.