How to create a completely new x509Certificate2 in .Net?
I google it from web, find many examples to ge开发者_StackOverflownerate a new x509Certificate2
from a file in .Net, but there is no example to show how to generate a completely new x509Certificate2
from the beginning in .net.
Is there any one that can tell me how to do it in .net?
Here's a code you can use:
static X509Certificate2 GenerateCertificate(string certName)
{
var keypairgen = new RsaKeyPairGenerator();
keypairgen.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024));
var keypair = keypairgen.GenerateKeyPair();
var gen = new X509V3CertificateGenerator();
var CN = new X509Name("CN=" + certName);
var SN = BigInteger.ProbablePrime(120, new Random());
gen.SetSerialNumber(SN);
gen.SetSubjectDN(CN);
gen.SetIssuerDN(CN);
gen.SetNotAfter(DateTime.MaxValue);
gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
gen.SetSignatureAlgorithm("MD5WithRSA");
gen.SetPublicKey(keypair.Public);
var newCert = gen.Generate(keypair.Private);
return new X509Certificate2(DotNetUtilities.ToX509Certificate((Org.BouncyCastle.X509.X509Certificate)newCert));
}
for this to work, don't forget to add reference to BouncyCastle library
Checkout CertificateRequest (Name Space: System.Security.Cryptography.X509Certificates)...
public static X509Certificate2 GenerateSelfSignedCertificate()
{
string secp256r1Oid = "1.2.840.10045.3.1.7"; //oid for prime256v1(7) other identifier: secp256r1
string subjectName = "Self-Signed-Cert-Example";
var ecdsa = ECDsa.Create(ECCurve.CreateFromValue(secp256r1Oid));
var certRequest = new CertificateRequest($"CN={subjectName}", ecdsa, HashAlgorithmName.SHA256);
//add extensions to the request (just as an example)
//add keyUsage
certRequest.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, true));
X509Certificate2 generatedCert = certRequest.CreateSelfSigned(DateTimeOffset.Now.AddDays(-1), DateTimeOffset.Now.AddYears(10)); // generate the cert and sign!
X509Certificate2 pfxGeneratedCert = new X509Certificate2(generatedCert.Export(X509ContentType.Pfx)); //has to be turned into pfx or Windows at least throws a security credentials not found during sslStream.connectAsClient or HttpClient request...
return pfxGeneratedCert;
}
Open ssl for creating x509 certificate
1.Download the Win64 Openssl from the below link.(Win64 OpenSSL v1.1.0j - 37mb installer) URL - https://slproweb.com/products/Win32OpenSSL.html
2.After installation set the system path environment variable.(path = C:\OpenSSL-Win64\bin)
3.Open command prompt and change the directory to desktop.
4.Command for key creation :
Private Key : openssl req -x509 -days 365 -newkey rsa:2048 -keyout cert-key.pem -out cert.pem
Enter the command and follow the instruction.
5.Now we have 2 files named cert-key.pem and cert.pem in desktop. To create the .pfx file run the below command
openssl pkcs12 -export -in cert.pem -inkey cert-key.pem -out x509-cert.pfx
and follow the instruction(enter the same password).
6.Command for public key creation :
openssl pkcs12 -in x509-cert.pfx -clcerts -nokeys -out x509-cert-public.pem
and follow the instruction.
7.Register the certificate to mmc.
You can use PINVOKE to call into Crypt32 to create a self signed certificate. There is some sample code available which will generate one and put it in the certificate store for you.
There's also Keith Brown's certificate generator, which is written in managed code and has a library you can use.
Alternatively you can just use BouncyCastle using the Org.BouncyCastle.X509.X509V3CertificateGenerator
and the use the utility methods in Org.BouncyCastle.Security.DotNetUtilities
and call ToX509Certificate()
.
If you want to create a request and have it signed by a CA that's actually easier in .NET, as most of those classes can be imported as COM interop DLLs. But that's a whole other question.
I think you can't do it using that API. But you can create one using Bouncy Castle (http://www.bouncycastle.org) and later convert that object to a X509Certificate2 object (BC has some utility class for doing that).
-edit- Take a look at these BC classes: X509V3CertificateGenerator and X509Certificate
The BC utility class that later will convert a BC X509Certificate object to a regular X509Certificate2 object is: DotNetUtilities
public X509Certificate2 GetCertificate()
{
var config = InitConfiguration();
var certificateSubject = "X509Subject";
var certificateStoreName = "X509StoreName";
var certificateStoreLocation = "X509StoreLocation";
var thumbPrint = "ThumbPrint";
var storeName = (StoreName)Enum.Parse(typeof(StoreName), certificateStoreName, true);
var storeLocation = (StoreLocation)Enum.Parse(typeof(StoreLocation), certificateStoreLocation, true);
var certificateStore = new X509Store(storeName, storeLocation);
certificateStore.Open(OpenFlags.ReadOnly);
foreach (var storeCertificate in certificateStore.Certificates)
{
if (storeCertificate.Thumbprint.ToLower(System.Globalization.CultureInfo.CurrentCulture) == thumbPrint.ToLower(System.Globalization.CultureInfo.CurrentCulture))
{return storeCertificate;
}
}
certificateStore.Close();
return null;
}
精彩评论