dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.47k stars 4.76k forks source link

Proposal: Add Ed25519 and Curve25519 Algorithms to System.Security.Cryptography #14741

Open janhenke opened 9 years ago

janhenke commented 9 years ago

The System.Security.Cryptography namespace contains several commonly used cryptographic algorithms. I propose the addition of two commonly used algorithms which are currently missing:

Both are based on the same elliptic curve. Many open source projects (e.g. OpenSSH, OpenBSD) seem to prefer this elliptic curve for use in elliptic curve cryptography (ECC). It is therefore beneficial to have these algorithms implemented in CoreFX.

The two algorithms should be included in the existing classes in the System.Security.Cryptography namespace, but it must be possible to explicitly ask for the usage of these algorithms.

saper commented 9 years ago

Definitely a good idea.

Daniel J. Bernstein "Can anything do better than elliptic curves?"

Daniel J. Bernstein papers on Curve25519

ellismg commented 9 years ago

/cc @sandkum, @bartonjs, @nguerrera

guardrex commented 9 years ago

Is asking for SHA256Cng for dnxcore50 related? ... mean in the sense of keeping community requests for expanded System.Security.Cryptography in the same issue, or should I ask in a separate issue? It's probably going to be needed for ADAL (source1, source2).

ellismg commented 9 years ago

I would prefer if you open another issue. Thanks!

bartonjs commented 9 years ago

@GuardRex That'd be a separate issue :smile:.

janhenke commented 9 years ago

Is this issue being worked on? Is any further information necessary?

bartonjs commented 9 years ago

The good news is that no further information is necessary :smile:. The bad news is that we're currently focused on getting cross-platform support caught up to the existing API, so no one is working on this currently.

Once we have cross-plat caught up, then we'll move on to new functionality in lockstep; and the first "new" thing that I can think of would be to start pulling over the elliptic curve types from the full framework (which, since we're borrowing code from full framework, isn't really new :smile:). And once that's done this becomes actionable.

So, hopefully that makes sense... it's definitely on the radar, but not quite yet on the schedule.

janhenke commented 9 years ago

Okay, I hope we can finish FreeBSD support in CoreFX soon then. I was just asking to make sure this topic is not forgotten.

bartonjs commented 8 years ago

Curve25519 should be usable once dotnet/corefx#8158 is completed (since it's an ECDH-only curve); but since it doesn't have a registered OID it isn't a first-class citizen. (It should work on Windows via a named curve using new Oid(null, "curve25519") since Windows does by-name lookup; but OpenSSL does by-value lookup and therefore can't discover it).

Ed25519 being a completely different algorithm will require more/unique work.

karelz commented 8 years ago

We need API proposal for each algorithm. Keep in mind that each new algorithm has to receive Microsoft crypto-board approval - we can help get it started, but there is no guarantee about the result.

andymac4182 commented 6 years ago

Is there any movement on this? Found a good looking library but it requires Span so waiting for that https://github.com/ektrah/nsec

damccull commented 6 years ago

Yeah, I'm also really interested in this. I've found several implementations in C# (including a port of a java implementation by Whisper Systems) but I would rather have one I can trust as legit. I mean, I trust Whisper Systems, but I disagree with gplv3 and they have licensed it there...plus I'm not sure I trust the company that ported it to C#.

So...we can has curve25519?

bartonjs commented 6 years ago

curve25519 will work as a named curve on Windows when ECDiffieHellman is added. It won't "just work" on Linux because OpenSSL keys curves by OID and curve25519 doesn't have an OID, but it can be created from parameters. It won't work at all on macOS because Security.framework only supports secp224r1, secp256r1, secp384r1 and secp521r1 (and not explicit curve parameters).

Meai1 commented 5 years ago

I hope this makes it soon into .NET Core 3 because as I understand it, all the other cyphers are actually not really considered secure anymore. There is pretty much only Curve25519 and it isnt supported in aspnet core yet... but maybe the larger point here is that I cant see the use of these enumeration values. I need to know what they mean compared to OpenSSL ciphersuite strings and since dotnet core apparently uses OpenSSL in the background anyway, why hide this information? There should really be some kind of helper method on the sslfeature saying ToOpenSSLCiphersuiteString() so I know what is actually coming in.

I really dont understand why the enums are so imprecise. ExchangeAlgorithmType.DiffieHellman could mean almost anything. Likewise RsaKeyX is not a term used anywhere except in .NET apparently. What's the point of these namings? Look at these here with the green checkmarks: http://safecurves.cr.yp.to/ How am I supposed to figure out in any reasonable timeframe what .NET supports. Not only that: What .NET supports in combination with: TLS version. OpenSSL version. Does dotnet bundle the openssl version? (Apparently not, which is likewise dangerous to me because if you work with openssl, you will know that every app is going to need a slightly different version and now good luck figuring out which one .NET loads at runtime)

bartonjs commented 5 years ago

as I understand it, all the other cyphers are actually not really considered secure anymore.

If you mean TLS ciphersuites, what .NET exposes as a platform and what it can do via TLS aren't the same thing.

As for the security of other ECC curves, all I can say is that the "SafeCurves" critera are written by the same person who proposed Curve25519 and that the TLS 1.3 RFC has secp256r1 as a mandatory support curve, and curve25519 as optional.

but maybe the larger point here is that I cant see the use of these enumeration values. ... Likewise RsaKeyX is not a term used anywhere except in .NET apparently. What's the point of these namings?

Assuming you're talking about ExchangeAlgorithmType, the enum was based off of SSL 2/SSL 3, before ECC was in use. A new issue asking for clarity on that enumeration (or other SslStream data enumerations) would be reasonable, but doesn't really belong in this issue.

Does dotnet bundle the openssl version?

No, .NET on Linux always uses the system managed version of OpenSSL.

(Apparently not, which is likewise dangerous to me because if you work with openssl, you will know that every app is going to need a slightly different version and now good luck figuring out which one .NET loads at runtime)

Most systems have at most two system versions of OpenSSL: 1.0.x or 1.1.x. (Or they'll also have LibreSSL, which claims to be OpenSSL 42). Those two are not compatible with each other, and can be both loaded into a process at once if needed.

.NET Core 2.1 and 2.2 prefer OpenSSL 1.0 when it's available, but use 1.1 if OpenSSL 1.0 isn't found (because when they were released they didn't understand OpenSSL 1.1, so adding it as a fallback is a more compatible in-place update).

.NET Core 3.0 prefers OpenSSL 1.1, but will use OpenSSL 1.0 when needed.

What .NET supports in combination with: TLS version.

SSL 2 is not supported on Linux. SSL 3 is dying. TLS 1.0, 1.1, and 1.2 are supported on all Linux distros, AFAIK. TLS 1.3 is available on distros which have OpenSSL 1.1.1 as a system library.

There should really be some kind of helper method on the sslfeature saying ToOpenSSLCiphersuiteString() so I know what is actually coming in.

SslStream in .NET Core 3.0 exposes the TLS ciphersuite negotiated via the new NegotiatedCipherSuite property. It returns an enum whose members are all named the IANA name of the ciphersuite, not the OpenSSL version (the OpenSSL version is usually the IANA one, but replace with - and drop the TLS prefix).

Any further discussion of TLS specifically should be a different issue; this issue is about exposing Curve25519 into the ECDiffieHellman class at runtime, and/or the algorithm EdDSA.

Meai1 commented 5 years ago

well just to show you, here are the results of what Google uses: https://www.ssllabs.com/ssltest/analyze.html?d=google.com&s=216.58.195.78&hideResults=on

Every single cipher suite that they enabled uses ECDH x25519. Not a single secp256r1 to be found. I think they probably picked this optional curve for good reason over the mandatory one, we can only speculate here but the internet is definitely saying that x25519 is better than secp256r1 and Google seems to agree.

gradx commented 4 years ago

Bump. Can we add X25519 and Ed25519 to the roadmap?

YasarYY commented 4 years ago

Despite there is no official support/documentation, I've defined the Curve25519 as a custom curve on .NET Core 3.1. And used ECDiffieHellman for key pair generation and shared secret calculation, constituting what's known as X25519.

As a counterpart, I used another crypto library over a different platform, for verification. (x-cube-cryptolib over stm32f103c8 dev board)

ECDiffieHellman/Curve25519 somehow generates correct key pairs and shared secret, which are coherent with the control library, even when curve's definition parameters are wrong. That is something which I didn't expect. I don't know how reliable this is but it works. Weird though...

For codes and details, stackoverflow question is here.

YasarYY commented 3 years ago

About Ed25519, this curve can be defined and used in .Net Core as described in this stackoverflow answer.

But this is working only on Windows 10. I would recommend using .Net Core-compliant libs like NSec or libsodium-core.

matbech commented 3 years ago

About Ed25519, this curve can be defined and used in .Net Core as described in this stackoverflow answer.

But this is working only on Windows 10. I would recommend using .Net Core-compliant libs like NSec or libsodium-core.

Thank you for that. I would be nice if someone could do some performance benchmarks. My guess is that the generic approach Microsoft takes with the custom curves is significantly less performant than the other optimized options.

alexandrehtrb commented 3 years ago

Hello, I am interested in contributing with Ed25519 algorithm for .NET, is there any way I can help? Do algorithms like this need to be exclusively interoped with the operating system? ED25519 is a nice algorithm and it's the one recommended by GitHub. It would be great for signing JWTs and for SSH keys. (a bit off-topic, it would be very good if Azure DevOps accepted ED25519 SSH keys, currently, it does not)

bartonjs commented 3 years ago

Do algorithms like this need to be exclusively interoped with the operating system?

Yep. On Windows our only crypto provider is Windows CNG (or Windows CAPI for the legacy CAPI types). On Linux it's only OpenSSL, and on macOS it's ideally Security.framework because one of these days I'm really truly going to rip the band-aid off and no longer support OpenSSL from macOS.

To my recollection, at least two of those don't have EdDSA at this time.

saper commented 3 years ago

OpenSSL 1.1.1 supports EdDSA with the Ed25519 and Ed448 curves

TriHyde commented 3 years ago

Does libSystem.Security.Cryptography.Native.OpenSsl pass the calls to the actual openssl installed into the system or is that a full implementation of the openssl API? Is that library closed-source?

bartonjs commented 3 years ago

Does libSystem.Security.Cryptography.Native.OpenSsl pass the calls to the actual openssl installed into the system?

Yes, libSystem.Security.Cryptography.Native.OpenSsl just handles loading the system OpenSSL and managing some more complex calls from managed code into native code.

annerajb commented 2 years ago

Do algorithms like this need to be exclusively interoped with the operating system?

Yep. On Windows our only crypto provider is Windows CNG (or Windows CAPI for the legacy CAPI types). On Linux it's only OpenSSL, and on macOS it's ideally Security.framework because one of these days I'm really truly going to rip the band-aid off and no longer support OpenSSL from macOS.

To my recollection, at least two of those don't have EdDSA at this time.

so does this mean that this proposal is blocked until both Windows and MacOS support ed25519?

Can we move the proposal forward even if it only works on linux with openssl 1.1?

if so what is the next step for this proposal?

annerajb commented 2 years ago

@bartonjs are you the right person or can you refer me to who can assist with this?

Seems to be stuck in limbo :(

annerajb commented 2 years ago

I wrote a proposal here.

I also have a fork where i did a lot of this work and got x509certificates and sslstream to happily load the private key from openssl.

Assuming that it's fine to implement this for a single platform (since it seems it has bene done before with a few other algorihtms)

https://github.com/dotnet/runtime/issues/63174

mnns commented 2 years ago

Any news? I'd really like to see non nist curves in .NET

bartonjs commented 2 years ago

Any news? I'd really like to see non nist curves in .NET

There are already a lot of non-NIST curves... the brainpool curves: https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.eccurve.namedcurves?view=net-6.0

Curve25519 also works for ECDH, on Windows. Ed25519 is a different algorithm, and not supported in enough of our platforms to provide enough usefulness / frustration.

Fabi commented 2 years ago

Any news? I'd really like to see non nist curves in .NET

There are already a lot of non-NIST curves... the brainpool curves: https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.eccurve.namedcurves?view=net-6.0

Curve25519 also works for ECDH, on Windows. Ed25519 is a different algorithm, and not supported in enough of our platforms to provide enough usefulness / frustration.

It's used in many places nowadays and it's a no go to not have support for it in .net (This includes Ed25519ph and Ed25519ctx)

anner-emed commented 2 years ago

Another example in case we where short on any. Microsoft entra verified credentials only supported algorithms

https://docs.microsoft.com/en-us/azure/active-directory/verifiable-credentials/verifiable-credentials-standards#supported-algorithms

zeroskyx commented 1 year ago

Any news on the topic? Would be really great to migrate some Java security workloads to .NET.

bartonjs commented 1 year ago

We have an approved API shape at #63174. But during implementation we found Apple's implementation to be non-conformant. Since we don't do crypto ourselves (for many reasons, including that government agencies don't like JITted crypto) and we don't add things in crypto unless they run on two major platforms, and since Windows doesn't do EdDSA/Ed25519... we put the plan on hold again.

Curve25519+ECDH works fine on Windows, but not on Linux or macOS. (That's not an exception to the above, it's just that Windows supports that curve as a named curve and the others don't... so it falls under "we added support for named curves")

ybot01 commented 1 year ago

Any update on this?

vanbukin commented 1 year ago

I want to highlight a use case for Ed25519. At the moment, I am working on implementing a library for Passkeys (WebAuthn) on the side of the Relying Party (forming parameters and validating responses on the backend of an ASP.NET Core application). To pass Fido Conformance, support for the Ed25519 algorithm is needed on the library side. The only implementation of Fido2 for .NET uses the third-party library NSec.Cryptography, which provides a set of bindings for libsodium with a managed wrapper around them. Since this directly affects security, it would be much better to use cryptography from BCL, not from third-party implementations.