Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Private key loaded with X509Certificate2.CreateFromPem is not usable for ECDH on Windows #115232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
PetSerAl opened this issue May 1, 2025 · 2 comments · Fixed by #115249
Closed
Assignees
Milestone

Comments

@PetSerAl
Copy link

PetSerAl commented May 1, 2025

Description

When certificate is both ECDSA and ECDH in terms of:

private static bool IsECDsa(X509Certificate2 certificate)
{
using (ECDsa? ecdsa = certificate.GetECDsaPublicKey())
{
return ecdsa is not null;
}
}
private static bool IsECDiffieHellman(X509Certificate2 certificate)
{
using (ECDiffieHellman? ecdh = certificate.GetECDiffieHellmanPublicKey())
{
return ecdh is not null;
}
}

Then private key loaded with X509Certificate2.CreateFromPem is not usable for ECDH on Windows.

Reproduction Steps

using System;
using System.Security.Cryptography.X509Certificates;

var pem = """
-----BEGIN CERTIFICATE-----
MIIBFDCBu6ADAgECAgkAvDLCg4b2/VwwCgYIKoZIzj0EAwIwDzENMAsGA1UEAwwE
VGVzdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowDzENMAsGA1UE
AwwEVGVzdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFxeYPoaE/s7F4GQqTE/
eGfWmhQIgxkVNYKZk7z4mfAylUmbZ6Axbt04eatl9RMOFjHFH20hOg51/300otK6
x1IwCgYIKoZIzj0EAwIDSAAwRQIhAJ8PLaxaX/mtYSaQ+Ar/xkesnkc69R6B59+Z
4GGcpS7FAiBe3mEFY/bmB3qJYSYRMGjytQ/98v5LYSZHAaDx87uZMQ==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgT0q0yhmyYKLP9yPB
SKubBJFheOfrvBquIkhIm+br38uhRANCAARcXmD6GhP7OxeBkKkxP3hn1poUCIMZ
FTWCmZO8+JnwMpVJm2egMW7dOHmrZfUTDhYxxR9tIToOdf99NKLSusdS
-----END PRIVATE KEY-----
""";
var certificate = X509Certificate2.CreateFromPem(pem, pem);
Console.WriteLine(certificate.GetECDsaPrivateKey() is null);
Console.WriteLine(certificate.GetECDiffieHellmanPrivateKey() is null);

Expected behavior

False
False

Actual behavior

False
True

Regression?

No response

Known Workarounds

Explicitly load private key with ECDiffieHellman:

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

var pem = """
-----BEGIN CERTIFICATE-----
MIIBFDCBu6ADAgECAgkAvDLCg4b2/VwwCgYIKoZIzj0EAwIwDzENMAsGA1UEAwwE
VGVzdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowDzENMAsGA1UE
AwwEVGVzdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFxeYPoaE/s7F4GQqTE/
eGfWmhQIgxkVNYKZk7z4mfAylUmbZ6Axbt04eatl9RMOFjHFH20hOg51/300otK6
x1IwCgYIKoZIzj0EAwIDSAAwRQIhAJ8PLaxaX/mtYSaQ+Ar/xkesnkc69R6B59+Z
4GGcpS7FAiBe3mEFY/bmB3qJYSYRMGjytQ/98v5LYSZHAaDx87uZMQ==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgT0q0yhmyYKLP9yPB
SKubBJFheOfrvBquIkhIm+br38uhRANCAARcXmD6GhP7OxeBkKkxP3hn1poUCIMZ
FTWCmZO8+JnwMpVJm2egMW7dOHmrZfUTDhYxxR9tIToOdf99NKLSusdS
-----END PRIVATE KEY-----
""";
var certificate = X509Certificate2.CreateFromPem(pem);
var key = ECDiffieHellman.Create();
key.ImportFromPem(pem);
certificate = certificate.CopyWithPrivateKey(key);
Console.WriteLine(certificate.GetECDsaPrivateKey() is null);
Console.WriteLine(certificate.GetECDiffieHellmanPrivateKey() is null);

Configuration

.NET SDK:
 Version:           9.0.203
 Commit:            dc7acfa194
 Workload version:  9.0.200-manifests.9df47798
 MSBuild version:   17.13.20+a4ef1e90f

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.26100
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\9.0.203\

Host:
  Version:      9.0.4
  Architecture: x64
  Commit:       f57e6dc747

.NET SDKs installed:
  9.0.203 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

As far as I understand, issue is specific for Windows.

Other information

On Windows CngKey for EC key marked with AlgorithmGroup ECDSA or ECDH. ECDH keys can be used in both algorithms, while ECDSA keys can be used only with ECDSA. As such when key should be usable in both algorithms, then it should be loaded as ECDH. Following code fragment load them as ECDSA:

Oids.EcPublicKey when IsECDsa(certificate) =>
ExtractKeyFromPem<ECDsa>(
keyPem,
s_EcPublicKeyPrivateKeyLabels,
static keyPem => CreateAndImport(keyPem, ECDsa.Create),
certificate.CopyWithPrivateKey),
Oids.EcPublicKey when IsECDiffieHellman(certificate) =>
ExtractKeyFromPem<ECDiffieHellman>(
keyPem,
s_EcPublicKeyPrivateKeyLabels,
static keyPem => CreateAndImport(keyPem, ECDiffieHellman.Create),
certificate.CopyWithPrivateKey),

Switch cases Oids.EcPublicKey when IsECDsa(certificate) and Oids.EcPublicKey when IsECDiffieHellman(certificate) should be reordered to load them as ECDH.

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label May 1, 2025
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

@vcsjones
Copy link
Member

vcsjones commented May 1, 2025

Thanks for the steps to reproduce and analysis. Will take a look at this soon.

@vcsjones vcsjones self-assigned this May 1, 2025
@vcsjones vcsjones added this to the 10.0.0 milestone May 1, 2025
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label May 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants