I have a certificate which having Friendly Name as well and I want to get the certificate using Friendly Name rather than Thumbprint. I don't see any method like FindByFriendlyName..., how to do this?
var thumbprint ="f454......"
var friendlyName = "ASP.NET Core...."
X509Certificate2Collection signingCerts = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
X509Certificate2Enumerator enumerator = signingCerts.GetEnumerator();
Built-in search can be done only against static fields, that never change for any given certificate. Friendly name is not static, it can be changed for any single certificate unlimited times. Thus, I would STRONGLY recommend to not rely on cert friendly name. EVER.
you can do manual filtering, by enumerating all certificates and checking for matching certificate, but it is very poor and fragile way.
If you want something that's a stable search value across cert renewals and is easy to read, you might try the subject name (if the cert has a decent subject name, other than localhost or something):
var subject ="org name signing cert......"
var friendlyName = "ASP.NET Core...."
X509Certificate2Collection signingCerts = store.Certificates.Find(X509FindType.FindBySubjectName, subject, true);
X509Certificate2Enumerator enumerator = signingCerts.GetEnumerator();
(You probably only want valid/non-expired certs, too, so use true for the last param.)
I have a use case to look up by FriendlyName. The code is below
//store variable
X509Store store;
//certificate variable
X509Certificate2 cert;
//init store using root and local machine
store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
//open store for read only
store.Open(OpenFlags.ReadOnly);
//find cert using linq
cert = store.Certificates.OfType<X509Certificate2>().FirstOrDefault(x => x.FriendlyName == "cert-friendlyname-here");
//close store
store.Close();
Related
Using server variables(Request.ServerVariables["CERT_SERVER_ISSUER"]), I can get a string representing the Server Certificate Issuer used in the connection.
I would like to access the actual certificate (X509Certificate if possible), so that I can further inspect the certificate.
I want to validate the server certificate in my ASP.NET code, to make sure nobody has simply clicked "..proceed anyway". Specifically I want to check the CA Root.
The way I understand it - typically browsers will not present a client certificate - so:
HttpContext.Current.Request.ClientCertificate
will be null/empty... I'm looking for the Server Certificate, and if possible the full chain of the Server Certificate so I can check the CA Root.
You can obtain certificates from the certificate store, you can do it by subject name, thumbprint, or something else if you want. You'll need to determine which of these you have available - and change the "find type" in this example:
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectName, "Subject Name", false);
if (certs.Count > 0)
{
// do something with: certs[0];
};
store.Close();
As I understand if someone doesn't want to use a custom domain name and instead plans on using *.azurewebsite.net domain assigned to the website by Azure, then HTTPS is already enabled with a certificate from Microsoft(I know this is not as secure as using a custom domain name). How would be I able to load this certificate programmatically. Currently I use the following method to load a certificate from local machine or Azure :
public static X509Certificate2 LoadFromStore(string certificateThumbprint,bool hostedOnAzure)
{
var s = certificateThumbprint;
var thumbprint = Regex.Replace(s, #"[^\da-zA-z]", string.Empty).ToUpper();
var store = hostedOnAzure ? new X509Store(StoreName.My, StoreLocation.CurrentUser) : new X509Store(StoreName.Root, StoreLocation.LocalMachine);
try
{
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var signingCert = certCollection.Find(X509FindType.FindByThumbprint, thumbprint, false);
if (signingCert.Count == 0)
{
throw new FileNotFoundException(string.Format("Cert with thumbprint: '{0}' not found in certificate store. Also number of certificates in the sotre was {1}", thumbprint, store.Certificates.Count));
}
return signingCert[0];
}
finally
{
store.Close();
}
}
I assume the culprit is the following line of code :
new X509Store(StoreName.My, StoreLocation.CurrentUser)
because when I get an exception it tells me there is no certificate in the store although I pass the correct certificate Thumbprint(I grab the thumbprint from Chrome manually).
You will not be able to access this certificate programmatically in your WebApp as this certificate is not really installed on the Azure WebApp. Azure WebApps have a front-end server which does a "kind of" SSL Offloading so the WebApp actually never has access to this particular certificate. Why exactly you want to read this certificate though ?
Typically if there is a need for certificates in WebApps, you would install client certificates and pass them to services for Authentication as mentioned in https://azure.microsoft.com/en-us/blog/using-certificates-in-azure-websites-applications/ and those certificates you can access programmatically (code snippet mentioned in the same article)
But I am not sure what exactly you want to achieve by reading the server certificate
I'm trying to loop through the Certificate store and identify if a certificate has a specific issuer. I located this article which provides the example of calling the certificates issuer:
Console.WriteLine("{0}Issuer: {1}{0}", Environment.NewLine, x509.Issuer);
But their example appears to require an input certificate. Is it possible to loop through the Certificates to identify if there are any on a machine that have the specific issuer?
Something like:
ForEach(cert in x509certificate2.store)
{
if (cert.issuer == SpecificIssuer)
{
console.writeline(cert.ToString());
}
}
The certificates I'm trying to isolate will belong to specific stores (?) such as [Console Root\Certificates (Local Computer)\Personal\Certificates] if it is possible to further filter the loops scope to just these specific stores.
You can use the Certificates.Find(), use the StoreName to specify your own store.
X509Store Store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
Store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection CertColl = Store.Certificates.Find(X509FindType.FindByIssuerName, "Microsoft",true);
foreach (X509Certificate2 Cert in CertColl)
Console.WriteLine("Cert: " + Cert.IssuerName.Name);
How do I access via C# the keys stored in the Certificate Enrollment Requests store?
I tried using:
var requestCertStore = new X509Store("Certificate Enrollment Requests",
StoreLocation.LocalMachine);
requestCertStore.Open(OpenFlags.MaxAllowed);
var certs = requestCertStore.Certificates;
but the certs collection does not contain the certificate I'm looking to access in the "Certificate Enrollment Requests" store. I also don't see any StoreName enum that corresponds to this store, so using the new X509Store(StoreName storeName, StoreLocation storeLocation) constructor isn't an option.
Is it not possible to retrieve these certs via C#/.NET?
The solution is to use "REQUEST" instead of "Certificate Enrollment Requests":
var requestCertStore = new X509Store("REQUEST", StoreLocation.LocalMachine);
requestCertStore.Open(OpenFlags.MaxAllowed);
var certs = requestCertStore.Certificates;
I found the hint here: Delete a pending certificate request.
I have to write a tool which validates if a X509 certificate is valid or not (input = cert path / subject and password). How can I do that? I don't know much about certs...
Take a look at X509Certificate2.Verify()
In general, RFC 3280 includes almost complete instructions regarding how to perform validation, however those instructions are very non-trivial. Additionally you would need to read RFC 2560 (OCSP) and implement OCSP client.
For most tasks you will find our TElX509CertificateValidator component perfectly suitable. It checks certificate paths, CRL and OCSP revocation (and checks validity of CRLs and OCSP responses as well). It is flexible and powerful enough and lets you perform additional, deeper checks on each step. Also this component can work with both Windows certificate storages and any other certificates, certificate chains and storages that you might have in files or in memory.
X509Certificate2.Verify Method performs a X.509 chain validation using basic validation policy.
This method builds a simple chain for the certificate and applies the base policy to that chain. If you need more information about a failure, validate the certificate directly using the X509Chain object.
X509Certificate2 cert = GetX509Cert();
// Verify the certificate
bool isValid = cert.Verify();
But there are many factors that can affect the validity of an X.509 certificate, including the expiration date, the identity of the signer, and the chain of trust. So you may need to write your custom code for validation depending on your specific requirements if Verify is not enough for you. So you can write your own validation code:
public static bool ValidateCertificate(X509Certificate2 certificate)
{
// Check the certificate has not expired
if (certificate.NotAfter < DateTime.UtcNow)
{
return false;
}
// Performs a X.509 chain validation using basic validation policy
if (!certificate.Verify())
{
return false;
}
// Check that the certificate's subject contains a specific string
if (!certificate.Subject.Contains("CN=example.com"))
{
return false;
}
// Check that the certificate's issuer contains a specific string
if (!certificate.Issuer.Contains("CN=Root CA"))
{
return false;
}
// All checks passed, certificate is valid
return true;
}
You have to initialize a new instance of the X509Certificate2 class to validate it. There are many constructors that allow to create a new instance by the:
certificate's file path
PEM file path or PEM file content
byte array with binary (DER) encoded or Base64-encoded X.509 data or PKCS7 (Authenticode) signed file data
unmanaged handle
var cert = new X509Certificate2(#"C:\yourcertfile.crt");
// or
var cert = new X509Certificate2(#"C:\yourcertfile.crt", password);
// or
var cert = new X509Certificate2(#"C:\yourcertfile.crt");
// or
var cert = X509Certificate2.CreateFromPemFile(#"C:\yourcertfile.pem");
// or
var cert = X509Certificate2.CreateFromPem(File.ReadAllText(#"C:\yourcertfile.pem"));
You can also open the current user or current machine certificate store via X509Store and find certificate by subject name.
X509Store store = new X509Store("MY",StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectName, "Your Cert's Subject Name", false);
var cert = certs.Count > 0 ? certs[0] : null;