Skip to content

Instantly share code, notes, and snippets.

@micah686
Last active April 15, 2023 02:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save micah686/4c4f66fbc217c2f5788a1cbaaa317a2d to your computer and use it in GitHub Desktop.
Save micah686/4c4f66fbc217c2f5788a1cbaaa317a2d to your computer and use it in GitHub Desktop.
TestCert-- Generate Certificate
using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace TestCert
{
internal class Complete
{
#region CA Cert
public static void SaveCACertAndKeys()
{
var cert = GenerateCertificate("TEST-CA");
string certPem = new string(PemEncoding.Write("CERTIFICATE", cert.RawData));
string keyPem;
if (cert.GetRSAPrivateKey() is RSA rsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", rsaKey.ExportPkcs8PrivateKey()));
}
else if (cert.GetECDsaPrivateKey() is ECDsa ecdsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", ecdsaKey.ExportPkcs8PrivateKey()));
}
else if (cert.GetDSAPrivateKey() is DSA dsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", dsaKey.ExportPkcs8PrivateKey()));
}
else
{
throw new CryptographicException("Unknown certificate algorithm");
}
Console.WriteLine(certPem);
Console.WriteLine(keyPem);
File.WriteAllText("pub.crt", certPem);
File.WriteAllText("priv.key", keyPem);
}
public static X509Certificate2 GenerateCertificate(string name)
{
string subjectName = $"CN={name}";
using (RSA rsa = RSA.Create(4096))
{
CertificateRequest req = new CertificateRequest(
subjectName,
rsa,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
req.CertificateExtensions.Add(
new X509BasicConstraintsExtension(false, false, 0, false));
req.CertificateExtensions.Add(
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
false));
req.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.8")
},
true));
req.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(req.PublicKey, false));
var selfSigned = req.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddYears(50));
return req.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-1),
DateTimeOffset.UtcNow.AddYears(50));
}
}
#endregion
private void GenNewPrivKey()
{
var rsa = RSA.Create(2048);
var secKey = rsa.ExportRSAPrivateKey();
var keyPem = new string(PemEncoding.Write("PRIVATE KEY", secKey));
File.WriteAllText("server.key", keyPem);
}
#region Pem Helper
public static void GetPemData(X509Certificate2 cert, string fileName)
{
byte[] certificateBytes = cert.RawData;
char[] certificatePem = PemEncoding.Write("CERTIFICATE", certificateBytes);
AsymmetricAlgorithm? key;
var rsaKey = cert.GetRSAPrivateKey();
key = rsaKey != null ? rsaKey : cert.GetECDsaPrivateKey();
//AsymmetricAlgorithm key = cert.GetRSAPrivateKey() ?? cert.GetECDsaPrivateKey();
byte[] pubKeyBytes = key.ExportSubjectPublicKeyInfo();
byte[] privKeyBytes = key.ExportPkcs8PrivateKey();
char[] pubKeyPem = PemEncoding.Write("PUBLIC KEY", pubKeyBytes);
char[] privKeyPem = PemEncoding.Write("PRIVATE KEY", privKeyBytes);
File.WriteAllText($"{fileName}.crt", new string(pubKeyPem));
File.WriteAllText($"{fileName}.key", new string(privKeyPem));
}
public static X509Certificate2 SaveCertAsPem(X509Certificate2 cert, string fileName)
{
string certPem = new string(PemEncoding.Write("CERTIFICATE", cert.RawData));
string keyPem;
if (cert.GetRSAPrivateKey() is RSA rsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", rsaKey.ExportPkcs8PrivateKey()));
}
else if (cert.GetECDsaPrivateKey() is ECDsa ecdsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", ecdsaKey.ExportPkcs8PrivateKey()));
}
else if (cert.GetDSAPrivateKey() is DSA dsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", dsaKey.ExportPkcs8PrivateKey()));
}
else
{
throw new CryptographicException("Unknown certificate algorithm");
}
File.WriteAllText($"{fileName}.crt", certPem);
File.WriteAllText($"{fileName}.key", keyPem);
var certAgain = X509Certificate2.CreateFromPem(certPem, keyPem);
return certAgain;
}
#endregion
}
}
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Net.Sockets;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace TestCert
{
internal class Complete2
{
//https://www.codeproject.com/Articles/5315010/How-to-Use-Certificates-in-ASP-NET-Core
static void Main2(string[] args)
{
Console.WriteLine("Hello, World!");
const string CERT_NAME = "TestCert";
const string CERT_PASS = "123456";
TestGen1();
var ca = GenerateCertificate("CA");
SaveCertAsPem(ca, "CA");
var ss = GenerateCertificateWithRSAKey("SERVER", ca);
//var ss = CreateSignedCert("CA.crt", "123456", "SERVER", "querty", "SERVER");
SaveCertAsPem(ss, "SERVER");
//File.WriteAllBytes($"{CERT_NAME}.crt", cert.Export(X509ContentType.Cert, CERT_PASS));
//File.WriteAllBytes("test.crt", cert.Export(X509ContentType.Pfx, "123456"));
Console.WriteLine("Cert generated");
//var contents = File.ReadAllText($"{CERT_NAME}.crt");
//Console.WriteLine(contents);
Console.ReadKey();
}
private static bool ValidateCert(X509Certificate2 rootCA, X509Certificate2 serverCert)
{
X509Chain x509Chain = new X509Chain();
x509Chain.ChainPolicy.ExtraStore.Add(rootCA);
x509Chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
x509Chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
x509Chain.Build(serverCert);
foreach (X509ChainElement x509ChainElement in x509Chain.ChainElements)
{
//var dh = x509ChainElement.Certificate.PublicKey.GetECDiffieHellmanPublicKey();
var foo = x509ChainElement.Certificate.GetPublicKeyString();
var bar = rootCA.GetPublicKeyString();
Console.WriteLine("Name: " + x509ChainElement.Certificate.GetNameInfo(X509NameType.SimpleName, false));
foreach (X509ChainStatus x509ChainStatus in x509ChainElement.ChainElementStatus)
Console.WriteLine("status: " + x509ChainStatus.StatusInformation);
if (x509ChainElement.ChainElementStatus.Length != 0 && (x509ChainElement.Certificate.Thumbprint != rootCA.Thumbprint))// || x509ChainElement.ChainElementStatus[0].Status != X509ChainStatusFlags.UntrustedRoot))
return false;
}
return true;
}
private static bool ValidateTestServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// If the certificate is a valid, signed certificate, return true.
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
{
return true;
}
// If there are errors in the certificate chain, look at each error to determine the cause.
if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
if (chain != null && chain.ChainStatus != null)
{
foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
{
if ((certificate.Subject == certificate.Issuer) &&
(status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
{
// Self-signed certificates with an untrusted root are valid.
continue;
}
else
{
if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
{
// If there are any other errors in the certificate chain, the certificate is invalid,
// so the method returns false.
return false;
}
}
}
}
// When processing reaches this line, the only errors in the certificate chain are
// untrusted root errors for self-signed certificates. These certificates are valid
// for default Exchange server installations, so return true.
return true;
}
else
{
// In all other cases, return false.
return false;
}
}
public static void TrySignCert(string caCert, string caKey, string newCertName)
{
string subjectName = $"CN={newCertName}";
var caPub = File.ReadAllText("CA_PEM.crt");
var caPriv = File.ReadAllText("CA_PEM.key");
var rootCA = X509Certificate2.CreateFromPem(caPub, caPriv);
var rsa = rootCA.GetRSAPrivateKey();
var request = new CertificateRequest(newCertName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(
new X509KeyUsageExtension(X509KeyUsageFlags.KeyAgreement | X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, true));
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection { new Oid("1.3.6.1.5.5.7.3.1"), new Oid("1.3.6.1.5.5.7.3.2") }, true));
SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddDnsName("localhost");
request.CertificateExtensions.Add(sanBuilder.Build());
var csr = request.CreateSelfSigned(DateTimeOffset.MinValue, DateTimeOffset.MaxValue);
var cert = csr.CopyWithPrivateKey(rsa);
byte[] certificateBytes = cert.RawData;
char[] certificatePem = PemEncoding.Write("CERTIFICATE", certificateBytes);
AsymmetricAlgorithm? key;
var rsaKey = cert.GetRSAPrivateKey();
key = rsaKey != null ? rsaKey : cert.GetECDsaPrivateKey();
//AsymmetricAlgorithm key = cert.GetRSAPrivateKey() ?? cert.GetECDsaPrivateKey();
byte[] pubKeyBytes = key.ExportSubjectPublicKeyInfo();
byte[] privKeyBytes = key.ExportPkcs8PrivateKey();
char[] pubKeyPem = PemEncoding.Write("PUBLIC KEY", pubKeyBytes);
char[] privKeyPem = PemEncoding.Write("PRIVATE KEY", privKeyBytes);
var srvPub = new string(pubKeyPem);
var srvPriv = new string(privKeyPem);
File.WriteAllText("SERVER.crt", srvPub);
File.WriteAllText("SERVER.key", srvPriv);
}
public static X509Certificate2 GenerateCertificateWithRSAKey(string name, X509Certificate2 rootCACert)
{
AsymmetricAlgorithm? key;
var rsaKey = rootCACert.GetRSAPrivateKey();
string subjectName = $"CN={name}";
CertificateRequest req = new CertificateRequest(
subjectName,
rsaKey,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
req.CertificateExtensions.Add(
new X509BasicConstraintsExtension(false, false, 0, false));
req.CertificateExtensions.Add(
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
false));
req.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.8")
},
true));
req.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(req.PublicKey, false));
var selfSigned = req.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddYears(50));
return req.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-1),
DateTimeOffset.UtcNow.AddYears(50));
}
public static IPAddress GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip;
}
}
return IPAddress.Loopback;
}
public static void TestGen1()
{
string Organization = "MirrorTube";
string CommonName = "MirrorTube.RootCA";
var CountryCode = "US";
var OrganizationalUnits = new[] { "Copyright (c), " + DateTime.UtcNow.ToString("yyyy") + " MirrorTube.RootCA" };
SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddIpAddress(GetLocalIPAddress());
sanBuilder.AddDnsName(Environment.MachineName);
sanBuilder.AddUserPrincipalName(Environment.OSVersion.ToString());
var dn = new StringBuilder();
dn.Append("CN=\"" + CommonName.Replace("\"", "\"\"") + "\"");
foreach (var ou in OrganizationalUnits)
{
dn.Append(",OU=\"" + ou.Replace("\"", "\"\"") + "\"");
}
dn.Append(",O=\"" + Organization.Replace("\"", "\"\"") + "\"");
dn.Append(",C=" + CountryCode.ToUpper());
var strDn = dn.ToString();
X500DistinguishedName distinguishedName = new X500DistinguishedName(strDn);
var rsaKey = RSA.Create(4096);
string subjectName = $"CN=CA";
CertificateRequest req = new CertificateRequest(
distinguishedName,
rsaKey,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
req.CertificateExtensions.Add(
new X509BasicConstraintsExtension(false, false, 0, false));
req.CertificateExtensions.Add(
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
false));
req.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.8")
},
true));
req.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(req.PublicKey, false));
req.CertificateExtensions.Add(sanBuilder.Build());
var selfSigned = req.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddYears(50));
SaveCertAsPem(selfSigned, "TEXTCRT");
}
public static X509Certificate2 CreateSelfSignedCert(string CommonName, string Password, string Destination, string FriendlyName = null, string[] DnsNames = null, DateTime? ExpirationBefore = null, DateTime? ExpirationAfter = null, bool IsCertificateAuthority = false, string CountryCode = "US", string Organization = "JCCE", string[] OrganizationalUnits = null)
{
SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
if (DnsNames == null)
{
sanBuilder.AddIpAddress(IPAddress.Loopback);
sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
sanBuilder.AddDnsName("localhost");
sanBuilder.AddDnsName(Environment.MachineName);
}
else
{
foreach (var dnsName in DnsNames)
{
sanBuilder.AddDnsName(dnsName);
}
}
if (CountryCode.Length != 2) CountryCode = "US";
if (OrganizationalUnits == null) OrganizationalUnits = new[] { "Copyright (c), " + DateTime.UtcNow.ToString("yyyy") + " JCCE" };
var dn = new StringBuilder();
dn.Append("CN=\"" + CommonName.Replace("\"", "\"\"") + "\"");
foreach (var ou in OrganizationalUnits)
{
dn.Append(",OU=\"" + ou.Replace("\"", "\"\"") + "\"");
}
dn.Append(",O=\"" + Organization.Replace("\"", "\"\"") + "\"");
dn.Append(",C=" + CountryCode.ToUpper());
dn.Append(",C=" + "JP");
var strDn = dn.ToString();
X500DistinguishedName distinguishedName = new X500DistinguishedName(strDn);
X509Certificate2 cert;
using (RSA rsa = RSA.Create(2048))
{
var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var usages = X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature;
if (IsCertificateAuthority) usages = usages | X509KeyUsageFlags.KeyCertSign;
request.CertificateExtensions.Add(new X509KeyUsageExtension(usages, false));
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
request.CertificateExtensions.Add(sanBuilder.Build());
if (IsCertificateAuthority) request.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, true, 1, true));
if (ExpirationAfter == null) { ExpirationAfter = DateTime.UtcNow.AddDays(-1).AddYears(10); }
if (ExpirationBefore == null) ExpirationBefore = DateTime.UtcNow;
var certificate = request.CreateSelfSigned(new DateTimeOffset(ExpirationBefore.Value), new DateTimeOffset(ExpirationAfter.Value));
if (FriendlyName == null) FriendlyName = CommonName;
cert = new X509Certificate2(certificate.Export(X509ContentType.Pfx, Password), Password, X509KeyStorageFlags.MachineKeySet);
File.WriteAllBytes(Destination, certificate.Export(X509ContentType.Pkcs12, Password));
}
return cert;
}
public static X509Certificate2 CreateSignedCert(string IssuerCertLocation, string IssuerPassword, string CommonName, string Password, string Destination, string FriendlyName = null, string[] DnsNames = null, DateTime? ExpirationBefore = null, DateTime? ExpirationAfter = null, string CountryCode = "US", string Organization = "JCCE", string[] OrganizationalUnits = null)
{
SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
if (DnsNames == null)
{
sanBuilder.AddIpAddress(IPAddress.Loopback);
sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
sanBuilder.AddDnsName("localhost");
sanBuilder.AddDnsName(Environment.MachineName);
}
else
{
foreach (var dnsName in DnsNames)
{
sanBuilder.AddDnsName(dnsName);
}
}
if (CountryCode.Length != 2) CountryCode = "US";
if (OrganizationalUnits == null) OrganizationalUnits = new[] { "Copyright (c), " + DateTime.UtcNow.ToString("yyyy") + " \"JCCE\"", "JcceEventBusServer" };
var dn = new StringBuilder();
dn.Append("CN=\"" + CommonName.Replace("\"", "\"\"") + "\"");
foreach (var ou in OrganizationalUnits)
{
dn.Append(";OU=\"" + ou.Replace("\"", "\"\"") + "\"");
}
dn.Append(";O=\"" + Organization.Replace("\"", "\"\"") + "\"");
dn.Append(";C=" + CountryCode.ToUpper());
dn.Append(";C=" + "JP");
var strDn = dn.ToString();
X500DistinguishedName distinguishedName = new X500DistinguishedName(strDn);
var issuerCert = new X509Certificate2(fileName: IssuerCertLocation, password: IssuerPassword, keyStorageFlags: X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
var uniqueId = Guid.NewGuid();
using (var rsa = RSA.Create(2048))
{
var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(
new X509KeyUsageExtension(X509KeyUsageFlags.KeyAgreement | X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, true));
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection { new Oid("1.3.6.1.5.5.7.3.1"), new Oid("1.3.6.1.5.5.7.3.2") }, true));
request.CertificateExtensions.Add(sanBuilder.Build());
if (ExpirationAfter == null) { ExpirationAfter = issuerCert.NotAfter.Date; } //DateTime.ParseExact(issuerCert.GetExpirationDateString(), "M/dd/yyyy h:mm:ss tt", CultureInfo.InvariantCulture); }
if (ExpirationBefore == null) ExpirationBefore = DateTime.UtcNow;
var certificate = request.Create(issuerCert, new DateTimeOffset(ExpirationBefore.Value), new DateTimeOffset(ExpirationAfter.Value), uniqueId.ToByteArray());
certificate = certificate.CopyWithPrivateKey(rsa);
if (FriendlyName == null) FriendlyName = CommonName;
var key = certificate.GetRSAPrivateKey();
File.WriteAllBytes(Destination, certificate.Export(X509ContentType.Pfx, Password));
return certificate;
}
//return uniqueId;
}
public static X509Certificate2 GenerateCertificate(string name)
{
string subjectName = $"CN={name}";
using (RSA rsa = RSA.Create(4096))
{
CertificateRequest req = new CertificateRequest(
subjectName,
rsa,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
req.CertificateExtensions.Add(
new X509BasicConstraintsExtension(false, false, 0, false));
req.CertificateExtensions.Add(
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
false));
req.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.8")
},
true));
req.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(req.PublicKey, false));
var selfSigned = req.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddYears(50));
return req.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-1),
DateTimeOffset.UtcNow.AddYears(50));
}
}
#region Pem Helper
public static void GetPemData(X509Certificate2 cert, string fileName)
{
byte[] certificateBytes = cert.RawData;
char[] certificatePem = PemEncoding.Write("CERTIFICATE", certificateBytes);
AsymmetricAlgorithm? key;
var rsaKey = cert.GetRSAPrivateKey();
key = rsaKey != null ? rsaKey : cert.GetECDsaPrivateKey();
//AsymmetricAlgorithm key = cert.GetRSAPrivateKey() ?? cert.GetECDsaPrivateKey();
byte[] pubKeyBytes = key.ExportSubjectPublicKeyInfo();
byte[] privKeyBytes = key.ExportPkcs8PrivateKey();
char[] pubKeyPem = PemEncoding.Write("PUBLIC KEY", pubKeyBytes);
char[] privKeyPem = PemEncoding.Write("PRIVATE KEY", privKeyBytes);
File.WriteAllText($"{fileName}.crt", new string(pubKeyPem));
File.WriteAllText($"{fileName}.key", new string(privKeyPem));
}
public static X509Certificate2 SaveCertAsPem(X509Certificate2 cert, string fileName)
{
string certPem = new string(PemEncoding.Write("CERTIFICATE", cert.RawData));
string keyPem;
if (cert.GetRSAPrivateKey() is RSA rsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", rsaKey.ExportPkcs8PrivateKey()));
}
else if (cert.GetECDsaPrivateKey() is ECDsa ecdsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", ecdsaKey.ExportPkcs8PrivateKey()));
}
else if (cert.GetDSAPrivateKey() is DSA dsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", dsaKey.ExportPkcs8PrivateKey()));
}
else
{
throw new CryptographicException("Unknown certificate algorithm");
}
File.WriteAllText($"{fileName}.crt", certPem);
File.WriteAllText($"{fileName}.key", keyPem);
var certAgain = X509Certificate2.CreateFromPem(certPem, keyPem);
return certAgain;
}
#endregion
}
}
using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace TestCert
{
internal class Old
{
private static X509Certificate2 buildSelfSignedServerCertificate()
{
string CertificateName = "MirrorTubeCert";
SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
//sanBuilder.AddIpAddress(IPAddress.Loopback);
//sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
sanBuilder.AddDnsName("localhost");
sanBuilder.AddDnsName(Environment.MachineName);
X500DistinguishedName distinguishedName = new X500DistinguishedName($"CN={CertificateName}");
using (RSA rsa = RSA.Create(2048))
{
var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(
new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, false));
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
request.CertificateExtensions.Add(sanBuilder.Build());
var certificate = request.CreateSelfSigned(new DateTimeOffset(DateTime.UtcNow.AddDays(-1)), new DateTimeOffset(DateTime.UtcNow.AddDays(3650)));
certificate.FriendlyName = CertificateName;
return new X509Certificate2(certificate.Export(X509ContentType.Pfx, "WeNeedASaf3rPassword"), "WeNeedASaf3rPassword", X509KeyStorageFlags.MachineKeySet);
}
}
private static void CreateCertificateForServerAuthentication()
{
// Generate private-public key pair
var rsaKey = RSA.Create(2048);
// Describe certificate
string subject = "CN=localhost";
// Create certificate request
var certificateRequest = new CertificateRequest(
subject,
rsaKey,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1
);
certificateRequest.CertificateExtensions.Add(
new X509BasicConstraintsExtension(
certificateAuthority: false,
hasPathLengthConstraint: false,
pathLengthConstraint: 0,
critical: true
)
);
certificateRequest.CertificateExtensions.Add(
new X509KeyUsageExtension(
keyUsages:
X509KeyUsageFlags.DigitalSignature
| X509KeyUsageFlags.KeyEncipherment,
critical: false
)
);
certificateRequest.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(
key: certificateRequest.PublicKey,
critical: false
)
);
certificateRequest.CertificateExtensions.Add(
new X509Extension(
new AsnEncodedData(
"Subject Alternative Name",
new byte[] { 48, 11, 130, 9, 108, 111, 99, 97, 108, 104, 111, 115, 116 }
),
false
)
);
var expireAt = DateTimeOffset.Now.AddYears(5);
var certificate = certificateRequest.CreateSelfSigned(DateTimeOffset.Now, expireAt);
// Export certificate with private key
var exportableCertificate = new X509Certificate2(
certificate.Export(X509ContentType.Cert),
(string)null,
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet
).CopyWithPrivateKey(rsaKey);
exportableCertificate.FriendlyName = "Ivan Yakimov Test-only Certificate For Server Authorization";
// Create password for certificate protection
var passwordForCertificateProtection = new SecureString();
foreach (var @char in "p@ssw0rd")
{
passwordForCertificateProtection.AppendChar(@char);
}
// Export certificate to a file.
File.WriteAllBytes(
"certificateForServerAuthorization.pfx",
exportableCertificate.Export(
X509ContentType.Pfx,
passwordForCertificateProtection
)
);
// Test correctness of export
var loadedCertificate = new X509Certificate2("certificateForServerAuthorization.pfx", passwordForCertificateProtection);
Console.WriteLine(loadedCertificate.FriendlyName);
}
private static void CreateCertificateForClientAuthentication()
{
// Generate private-public key pair
var rsaKey = RSA.Create(2048);
// Describe certificate
string subject = "CN=Ivan Yakimov";
// Create certificate request
var certificateRequest = new CertificateRequest(
subject,
rsaKey,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1
);
certificateRequest.CertificateExtensions.Add(
new X509BasicConstraintsExtension(
certificateAuthority: false,
hasPathLengthConstraint: false,
pathLengthConstraint: 0,
critical: true
)
);
certificateRequest.CertificateExtensions.Add(
new X509KeyUsageExtension(
keyUsages:
X509KeyUsageFlags.DigitalSignature
| X509KeyUsageFlags.KeyEncipherment,
critical: false
)
);
certificateRequest.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(
key: certificateRequest.PublicKey,
critical: false
)
);
var expireAt = DateTimeOffset.Now.AddYears(5);
var certificate = certificateRequest.CreateSelfSigned(DateTimeOffset.Now, expireAt);
// Export certificate with private key
var exportableCertificate = new X509Certificate2(
certificate.Export(X509ContentType.Cert),
(string)null,
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet
).CopyWithPrivateKey(rsaKey);
exportableCertificate.FriendlyName = "Ivan Yakimov Test-only Certificate For Client Authorization";
// Create password for certificate protection
var passwordForCertificateProtection = new SecureString();
foreach (var @char in "p@ssw0rd")
{
passwordForCertificateProtection.AppendChar(@char);
}
// Export certificate to a file.
File.WriteAllBytes(
"certificateForClientAuthorization.pfx",
exportableCertificate.Export(
X509ContentType.Pfx,
passwordForCertificateProtection
)
);
// Test correctness of export
var loadedCertificate = new X509Certificate2("certificateForClientAuthorization.pfx", passwordForCertificateProtection);
Console.WriteLine(loadedCertificate.FriendlyName);
}
public static X509Certificate2 GenerateCertificate(string name)
{
string subjectName = $"CN={name}";
using (RSA rsa = RSA.Create(4096))
{
CertificateRequest req = new CertificateRequest(
subjectName,
rsa,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
req.CertificateExtensions.Add(
new X509BasicConstraintsExtension(false, false, 0, false));
req.CertificateExtensions.Add(
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
false));
req.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.8")
},
true));
req.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(req.PublicKey, false));
var selfSigned = req.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddYears(50));
return req.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-1),
DateTimeOffset.UtcNow.AddYears(50));
}
}
}
}
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Net.Sockets;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace TestCert
{
internal class Program
{
//https://www.codeproject.com/Articles/5315010/How-to-Use-Certificates-in-ASP-NET-Core
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
const string CERT_NAME = "TestCert";
const string CERT_PASS = "123456";
//TestGen1();
CreateRootCACert();
var rootPub = File.ReadAllText($"RootCA.crt");
var rootKey = File.ReadAllText($"RootCA.key");
var rootCA = X509Certificate2.CreateFromPem(rootPub, rootKey);
var normalCert = CreateNormalCert(rootCA, "SERVER");
var isValid = rootCA.GetPublicKeyString().Equals(normalCert.GetPublicKeyString());
Console.WriteLine("Cert generated");
//var contents = File.ReadAllText($"{CERT_NAME}.crt");
//Console.WriteLine(contents);
Console.ReadKey();
}
private static bool ValidateCert(X509Certificate2 rootCA, X509Certificate2 serverCert)
{
X509Chain x509Chain = new X509Chain();
x509Chain.ChainPolicy.ExtraStore.Add(rootCA);
x509Chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
x509Chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
x509Chain.Build(serverCert);
foreach (X509ChainElement x509ChainElement in x509Chain.ChainElements)
{
//var dh = x509ChainElement.Certificate.PublicKey.GetECDiffieHellmanPublicKey();
var foo = x509ChainElement.Certificate.GetPublicKeyString();
var bar = rootCA.GetPublicKeyString();
Console.WriteLine("Name: " + x509ChainElement.Certificate.GetNameInfo(X509NameType.SimpleName, false));
foreach (X509ChainStatus x509ChainStatus in x509ChainElement.ChainElementStatus)
Console.WriteLine("status: " + x509ChainStatus.StatusInformation);
if (x509ChainElement.ChainElementStatus.Length != 0 && (x509ChainElement.Certificate.Thumbprint != rootCA.Thumbprint))// || x509ChainElement.ChainElementStatus[0].Status != X509ChainStatusFlags.UntrustedRoot))
return false;
}
return true;
}
public static X509Certificate2 CreateRootCACert()
{
const string ORGANIZATIONAL_UNIT = "RootCA";
var cert = GenerateCert(ORGANIZATIONAL_UNIT, null);
SaveCertAsPem(cert, ORGANIZATIONAL_UNIT);
return cert;
}
public static X509Certificate2 CreateNormalCert(X509Certificate2 rootCA, string name)
{
var rsaKey = rootCA.GetRSAPrivateKey();
if (rsaKey != null)
{
var cert = GenerateCert(name, rsaKey);
SaveCertAsPem(cert, name);
return cert;
}
return null;
}
private static IPAddress GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip;
}
}
return IPAddress.Loopback;
}
private static X509Certificate2 GenerateCert(string CommonName, RSA? rsaKey)
{
const string ORGANIZATION = "MirrorTube";
if (rsaKey == null)
{
rsaKey = RSA.Create(4096);
}
var OrganizationalUnit = $"{ORGANIZATION}.{CommonName}, Copyright (c) {DateTime.UtcNow.ToString("yyyy")}";
SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddIpAddress(GetLocalIPAddress());
sanBuilder.AddDnsName(Environment.MachineName);
var sb = new StringBuilder();
sb.Append("CN=\"" + $"{ORGANIZATION}.{CommonName}".Replace("\"", "\"\"") + "\"");
sb.Append(",OU=\"" + OrganizationalUnit.Replace("\"", "\"\"") + "\"");
sb.Append(",O=\"" + ORGANIZATION.Replace("\"", "\"\"") + "\"");
sb.Append(",C=" + "US");
var dn = sb.ToString();
X500DistinguishedName distinguishedName = new X500DistinguishedName(dn);
string subjectName = $"CN=CA";
CertificateRequest req = new CertificateRequest(
distinguishedName,
rsaKey,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
req.CertificateExtensions.Add(
new X509BasicConstraintsExtension(false, false, 0, false));
req.CertificateExtensions.Add(
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
false));
req.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.8")
},
true));
req.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(req.PublicKey, false));
req.CertificateExtensions.Add(sanBuilder.Build());
var selfSigned = req.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddYears(50));
return selfSigned;
}
#region Pem Helper
public static void GetPemData(X509Certificate2 cert, string fileName)
{
byte[] certificateBytes = cert.RawData;
char[] certificatePem = PemEncoding.Write("CERTIFICATE", certificateBytes);
AsymmetricAlgorithm? key;
var rsaKey = cert.GetRSAPrivateKey();
key = rsaKey != null ? rsaKey : cert.GetECDsaPrivateKey();
//AsymmetricAlgorithm key = cert.GetRSAPrivateKey() ?? cert.GetECDsaPrivateKey();
byte[] pubKeyBytes = key.ExportSubjectPublicKeyInfo();
byte[] privKeyBytes = key.ExportPkcs8PrivateKey();
char[] pubKeyPem = PemEncoding.Write("PUBLIC KEY", pubKeyBytes);
char[] privKeyPem = PemEncoding.Write("PRIVATE KEY", privKeyBytes);
File.WriteAllText($"{fileName}.crt", new string(pubKeyPem));
File.WriteAllText($"{fileName}.key", new string(privKeyPem));
}
public static X509Certificate2 SaveCertAsPem(X509Certificate2 cert, string fileName)
{
string certPem = new string(PemEncoding.Write("CERTIFICATE", cert.RawData));
string keyPem;
if (cert.GetRSAPrivateKey() is RSA rsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", rsaKey.ExportPkcs8PrivateKey()));
}
else if (cert.GetECDsaPrivateKey() is ECDsa ecdsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", ecdsaKey.ExportPkcs8PrivateKey()));
}
else if (cert.GetDSAPrivateKey() is DSA dsaKey)
{
keyPem = new string(PemEncoding.Write("PRIVATE KEY", dsaKey.ExportPkcs8PrivateKey()));
}
else
{
throw new CryptographicException("Unknown certificate algorithm");
}
File.WriteAllText($"{fileName}.crt", certPem);
File.WriteAllText($"{fileName}.key", keyPem);
var certAgain = X509Certificate2.CreateFromPem(certPem, keyPem);
return certAgain;
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment