I'm developing a library which generates XML data and signates the generated XML. I've installed a pkcs12 certificate (generated with OpenSSL from pem file) into the windows certificate store.
I'm loading the certificate from C# code with
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 cert = null;
foreach (var item in store.Certificates)
{
if (item.SubjectName.Name.Contains("CN=IDENTIFIER"))
{
cert = item;
break;
}
}
store.Close();
In my case the CN identifier is: my prename + surname. The cert comes from a third party. So I think I have no influence on the identifiers.
And here comes the question:
Is there any way to identify exactly this certificate from C#. In future it could be possible, that multiple certificates have the same X509 parameters (CN etc etc).
Thank you in advance.
Yes, it's possible that CN contains the same identifier (eg. when the certificate is issued for business entity).
Certificates are usually distinguished by one of following combinations:
1) Issuer name (not CN, but RDN, complete name record with multiple fields) + certificate serial number (it's unique within one CA)
2) Issuer name + certificate hash
If you don't know the issuer name before searching for the certificate, you can present the list of found certificates to the user and once he select one of certificates, store certificate hash for future reference.
On smaller systems (end-user's computer) the number of certificates in MY store is usually small and the chance of hash collision is minimal. On large systems the chance is higher and that's why Issuer name is used as well.
Expanding on Eugene's answer...
The Certificates property of X509Store is an X509CertificateCollection.
You'll probably be interested in its Find method and the X509FindType. It offers a number of ways to search for a certificate. Strictly speaking, both the subject DN and the subject alternative names should matter to identify the entity associated with a certificate. However, few tools do this from a presentation point of view (this could get quite cluttered in a table for example).
As GregS and Eugene pointed out, the certificate thumbprint (also known as fingerprint/hash in other tools) will identify a specific certificate uniquely, irrespectively of its issuer. It can be used with X509FindType.
Thumbprints are used in multiple places in the Windows/.Net/SSL world. In particular, it's the way to pick a given certificate to install on an HTTPS port.
Related
I am using the X509Store in C# DotNet to traverse the certificate stores. However, I am not clear on what the difference is between a certificate location and a certificate store. For example, the locations are LocalUser and LocalMachine. Examples of Stores are My (Personal) and Root. What is the difference between the Personal store on LocalMachine versus Personal store on LocalUser? What does it even mean to have a Personal store on LocalMachine?
There are a few purposed stores (C# name in bold, UI display name in parenthetical italics):
My (Personal): when searching for a leaf/end-entity certificate this store is usually what gets searched. This is usually the only store that has certificates with associated private keys.
If you browse to a site using client authentication certificates IE will choose candidate certs from the My store. (Forward reference: The location for this is CurrentUser)
When configuring IIS from a GUI it will show certificates from the My store. (Forward reference: The location for this is LocalMachine)
Root (Trusted Root Certificate Authorities): When doing a chained-trust decision, such as in TLS, if the other end of the chain is represented in this store then the original cert is trusted.
In addition to the certs explicitly in this store it exposes a virtual view over AuthRoot.
AuthRoot (Third-Party Root Certification Authorities): When registering an additional trusted root you "should" do it in the 3rd party store, for... reasons? While the LocalMachine one seems to work fine, the CurrentUser one seems to mostly be for show.
CertificateAuthority (Intermediate Certificate Authorities, known as "CA" to the underlying system): This is a repository of known intermediate certificates. When doing a chain build the system will look for a parent here, then in Root, then maybe over the Internet. If the chain was trustworthy then the certs in the middle of the chain may be cached here for future lookups.
Disallowed (Untrusted Certificates): If a part of a certificate chain is found in this store, the chain is considered untrustworthy.
AddressBook (Other People): A collection of certificate that you know about. Yep, about that specific. It gets searched by some programs/libraries when trying to match a peer certificate. For example, a find-by-issuer-and-serial-number notice in SignedXml.
There are a couple more standard ones, you can read about them at TechNet. You can also create your own certificate store using the X509Store(string, StoreLocation) overload. (It's sometimes useful for managing applications, but the certificate manager UI gets a bit confused when you have private keys in a custom store; it expects them only in the My store).
So that's StoreName. StoreLocation is perhaps better thought of as "store owner". A standard user could decide that they trust certificates issued by some private CA, so they could add it to their Root store. Since it's their store it won't affect any other users on the system. The system itself also owns stores. For example, the TLS certificate for the computer really belongs to "the computer", and multiple administrators may be involved with managing it. Since it's pretty unusual to search through your friend's stuff, the StoreLocation comes down to "me, as a user" (CurrentUser) or "this computer" (LocalMachine) for which store to use.
Things get slightly murky now: On Windows almost every CurrentUser store (with a notable exception of the My store) exposes a view into the LocalMachine equivalent store. So when you enumerate the certificates in CurrentUser\Root you're getting both the certificates explicitly added to CurrentUser\Root and also the certificates explicitly added to LocalMachine\Root. This can cause confusion since you can see a certificate when enumerating, call Remove with it as an argument, and it's still there when enumerating again.
In my experience, most interactions with cert stores are to the My store. At which point the decision tree comes down to something like this:
Am I a service with a dedicated user account?
new X509Store(StoreName.My, StoreLocation.CurrentUser)
Am I service without a dedicated user account?
new X509Store(StoreName.My, StoreLocation.LocalMachine)
Else
new X509Store(StoreName.My, StoreLocation.CurrentUser)
But that's a big generalization.
The personal store for LocalMachine contains machine certificates. An example of a certificate that lives in such store is a SSL certificate that is used by IIS to protect HTTP traffic. There is only one such store on the machine.
The personal store for LocalUser contains user certificates. An example of such certificate is an S/MIME certificate used to sign email messages. Each user has his/her own store of this type.
I'm using C#.NET and need to install a bunch of certificates into the Windows certificate store.
I need to check which of those certificates are root certificates (i.e. self-signed), so I can install them into the "Trusted root certificates" store.
I'm using the standard X509Certificate2 class. My current idea is to check whether the Issuer and Subject are the same.
I've noticed that X509Certificate2 has Issuer - IssuerName and Subject - SubjectName.
Is it better to compare Issuer to Subject, or IssuerName to SubjectName? Or doesn't it really matter?
Also, is this a reliable method or would I be better off using another approach?
See this post: java - Find if a certificate is self signed or CA signed
While it's not C#, the comment from the solution notes
If the subject and issuer are the same, it is self-signed
means you're correct about the way you're trying to validate it.
IssuerName and SubjectName return a DistinguishedName which contains RawData (a byte[] containing the raw information for the issuer/subject). You'd be best off comparing this field, though I believe comparing Subject and Issuer is just as valid.
So, you could write something like this:
public static bool IsSelfSigned(X509Certificate2 cert)
{
return cert.SubjectName.RawData.SequenceEqual(cert.IssuerName.RawData);
}
We have a requirement where we need to be able to encrypt/decrypt the query string as below:
http://oursite.com/login?uname=encryptedUName&fname=encryptedFname&lname=encryptedLname.
The way it works is that our company supplies the CSV of records to third party vendors. The third party vendors then generated the above url and sends to the customer by email marketing.
So, I'm thinking of
encrypting the records in CSV file
Third party vendors just parses the encrypted text and generates the email.
When user click on link the user comes to our site.
We then decrypt and prepopulate the form fields.
The file content may look like below:
*login?uname=encryptedUName&fname=encryptedFname&lname=encryptedLname.
login?uname=encryptedUName&fname=encryptedFname&lname=encryptedLname.*
Questions:
Should I use X509 certificate to encrypt and decrypt?
Or, should I use RSA?
How do I determine whether X509 or RSA?
Thanks.
A digital certificate works on top of a public & private key pair (asymmetric encryption). What a certificate adds is trust.You can sign a certificate using Certificate Authorities and create a trust chain.
In your case it doesn't seem as though you would need a certificate because you manage the encryption/decryption by yourself and your vendors know you and don't need a third party to verify you are who you say you are.
But, you may use a self-signed certificate as a key container if it's simpler for your vendors.
I have two serialized certificates in the DB from which I can construct the X509Certificate. How to tell if one certificate is signed by the other. I don't want to check based on the IssuerName as it is not reliable(for my scenario).
IssuerName property and Authority Key Identifier extension are the way to find relationships between certificates. Once you match them, you can verify if the supposedly parent certificate is actually the CA certificate of the one being checked. I am not sure that such checks are possible with .NET Framework alone, and our SecureBlackbox does this easily, with one method.
I'm using ITextSharp in order to read certificate informations from digitally signed pdf document.
The ITextSharp.Text.Pdf.PdfPKCS7 class exposes three properties:
Certificates (as list)
SignCertificate (as single object)
SignCertificateChain (as list)
How can I combine these three properties in order to achieve all info about a single certificate?
I'd be able to show all certificate path (all nested certificates).
Certificates gives you the list in no particular order, including certificates that weren't used for the main signature.
SignCertificate gives you the certificate of the actual signer.
SignCertificateChain gives you the list where the first Certificate is the SignCertificate, the next is the certificate of the instance that issued the SignCertificate, the next is the certificate of the instance that issued the previous certificate, and so on. This can return less certificates than Certificates, because only the certificates used for the main signature will be returned.
So you don't need to 'combine' the properties to show the certificate path, you just need SignCertificateChain. Note that your question isn't entirely clear:
'all info about a single certificate'
kind of contradicts with
'show all certificate path (all nested certificates)'
If you want to visualize the chain that resulted into the signing certificate, you need to look at more than a single certificate (unless the certificate was self-signed in which case there's only one element in the chain).