Я хочу иметь возможность генерировать сертификаты CA Root и сервера с использованием .NET. Конечная цель состоит в том, чтобы использовать их для обеспечения межсервисных GRPC Comms, но сейчас все работает локально. OpenSSL, все работает так, как и ожидалось, включая локальную службу GRPC .NET. Я думаю, что это связано с тем, что по какой -то причине код .NET не может получить доступ к частному ключу, хотя IIS может.
В следующем фрагменте кода, пытаясь получить доступ к PrivateKey для .NET, сгенерированного сертификационными бросками. />public void ReadDifferentCerts()
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindBySubjectName, "MyMachine", false);
var dotNetCert = certs.Find(X509FindType.FindByIssuerName, "DotNetRootCA", false).First();
var openSslCert = certs.Find(X509FindType.FindByIssuerName, "OpenSSLRootCA", false).First();
}
Многие решения по этому вопросу вращаются вокруг разрешений к ключу, и я могу получить доступ к ключу, если я импортирую файл PFX в хранилище текущего пользователя, Но мои вопросы:
, как отличается версия OpenSSL? Какой флаг мне нужно установить в версии .NET? Насколько я могу сделать, все параметры одинаковы, они выглядят почти идентично в магазине. Частный ключ 100% существует в файле PFX, поскольку IIS может использовать его, а один и тот же файл работает в текущем хранилище пользователя.public void GenerateAndWriteToDisk()
{
var rootCA = BuildRootCertificate();
Thread.Sleep(TimeSpan.FromSeconds(2));
var serverCert = BuildServerCertificate(rootCA);
var outputdir = @"C:\dev\certs";
File.WriteAllBytes(Path.Combine(outputdir, "DotNetRootCACert.crt"), rootCA.Export(X509ContentType.Cert));
File.WriteAllBytes(Path.Combine(outputdir, "LAPTOP-80-DotNet.pfx"), serverCert.Export(X509ContentType.Pfx, "word"));
}
public static X509Certificate2 BuildRootCertificate()
{
using (var rsa = RSA.Create(3072))
{
var request = new CertificateRequest("C=GB,O=MyCompany,CN=DotNetRootCA", rsa, HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
var subjectIdentifier = new X509SubjectKeyIdentifierExtension(new PublicKey(rsa), false);
request.CertificateExtensions.Add(subjectIdentifier);
request.CertificateExtensions.Add(X509AuthorityKeyIdentifierExtension.CreateFromSubjectKeyIdentifier(subjectIdentifier));
request.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
var cert = request.CreateSelfSigned(DateTimeOffset.Now,
DateTimeOffset.Now.AddDays(1825));
return cert;
}
}
public static X509Certificate2 BuildServerCertificate(X509Certificate2 rootCaCertificate)
{
using (var rsa = RSA.Create(3072))
{
var request = new CertificateRequest("O=MyCompany,OU=DevSecOps,CN=MyMachine", rsa, HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(X509AuthorityKeyIdentifierExtension.CreateFromCertificate(rootCaCertificate, true, false));
request.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(new PublicKey(rsa), false));
request.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false,
0, false));
var keyUsages = new X509KeyUsageExtension(
X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment |
X509KeyUsageFlags.DigitalSignature, false);
request.CertificateExtensions.Add(keyUsages);
var sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddDnsName("MyMachine");
sanBuilder.AddDnsName("localhost");
sanBuilder.AddIpAddress(IPAddress.Loopback);
sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
request.CertificateExtensions.Add(sanBuilder.Build());
var serialNumber = GetSerialNumber();
var certificate = request.Create(rootCaCertificate, DateTimeOffset.UtcNow,
DateTimeOffset.UtcNow.AddDays(365), serialNumber);
return certificate.CopyWithPrivateKey(rsa);
}
}
< /code>
powerShell /openssl Generation < /p>
function ExecOpenSsl([string]$sslArgs)
{
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "openssl"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.CreateNoWindow = $true
$pinfo.Arguments = $sslArgs
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
Write-Host "stdout: $stdout"
Write-Host "stderr: $stderr"
Write-Host "exit code: " + $p.ExitCode
}
$dir = 'C:\dev\certs'
$caKeyName = "$dir\OpenSslRootCaKey.key"
$caCertName = "$dir\OpenSSlRootCaCert.crt"
$serverKeyName = "$dir\OpenSslServerKey.key"
$serverCsr = "$dir\OpenSslServerReq.csr"
$serverExtension = "$dir\OpenSslServerExtensions.ext"
$serverCert = "$dir\LAPTOP-80-OpenSsl.crt"
$serverPfx = "$dir\LAPTOP-80-OpenSsl.pfx"
Set-Location $dir
$caPass = 'word' # (New-Guid).ToString()
$serverPass = 'word' #(New-Guid).ToString()
ExecOpenSsl -sslArgs "genrsa -aes128 -passout pass:$($caPass) -out $caKeyName 3072"
ExecOpenSsl -sslArgs "req -x509 -new -nodes -key $caKeyName -sha256 -days 1825 -out $caCertName -subj /CN=OpenSSLRootCA/O=MyCompany/C=GB/ -passin pass:$($caPass)"
ExecOpenSsl -sslArgs "genrsa -aes128 -passout pass:$($serverPass) -out $serverKeyName 3072"
$extension=@(
"authorityKeyIdentifier=keyid,issuer"
"basicConstraints=CA:FALSE"
"keyUsage = digitalSignature, keyEncipherment, dataEncipherment"
"subjectAltName = @alt_names"
""
"[alt_names]"
"DNS.1 = MyMachine"
"DNS.2 = localhost"
"IP.1 = 127.0.0.1"
"IP.2 = ::1"
)
Set-Content -Path $serverExtension -Value ($extension -join ([Environment]::NewLine)) -NoNewline
ExecOpenSsl -sslArgs "req -new -key $serverKeyName -passin pass:$($serverPass) -out $serverCsr -subj /CN=MyMachine/OU=DevSecOps/O=MyCompany/"
ExecOpenSsl -sslArgs "x509 -req -in $serverCsr -CA $caCertName -CAkey $caKeyName -passin pass:$($caPass) -CAcreateserial -out $serverCert -days 365 -sha256 -extfile $serverExtension"
ExecOpenSsl -sslArgs "pkcs12 -export -out $serverPfx -inkey $serverKeyName -in $serverCert -passin pass:$($serverPass) -passout pass:$($serverPass)"
Подробнее здесь: https://stackoverflow.com/questions/795 ... t-can-with
Не удается получить доступ к закрытому ключу через код для .NET, сгенерированного сертификатом, но может с открытым серт ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение