When mounting the card in the reader a certificate will be installed in the personal store, this certificate is then used by my WCF Client Server application for communication.
If I remove the card the certificates will also be removed from the store. If Im is in the middle of a started session I will not get any exception it will continue to work just as if the card was still in the reader? Is this by design? Does it mean that the communication will work as long as I dont try to read the certificate from the store again?
BestRegards
A certificate is a confirmed correspondence between a public key and an identity. There is no pressing need to delete the certificate when the card is removed, since this public key may still be useful to verify signed messages of that sender. X.509 certificates also have expiration dates to address the removal topic, similarly revocation lists. So while the private key (depending on configuration) may just be used as long as card is in place, the public key may exceed this by far.
Have a look at these pages as well:
http://technet.microsoft.com/en-us/library/ff404287(v=ws.10).aspx
http://technet.microsoft.com/en-us/library/ff404288(v=ws.10).aspx
And most of all, keep in mind that a smart card is usually only needed to initiate/open a session
Related
In my project, I need to check and validate client certificate for each users' request and then give them access to calling my APIs. My users are machines (other API or library). They append a certificate(s) to their request and send it to my hosted API.
I implement a custom authentication handler and retrieve client certificates successfully. Right now, I compare client certificate with a list of valid certifications in my appsetting.json (Thumbprint, Issuer and Serial number).
If all of these three properties are same as the client-certification, I return return Task.FromResult(AuthenticateResult.Success(ticket)); otherwise I return
return Task.FromResult(AuthenticateResult.Fail("certificate is not valid"));
everything works fine but I do not feel good about how I validated client certificate. I would like to know if there is elegant way for validating client certificate rather than my solution in ASP.NET CORE.
Issuer and Serial number are controllable by an attacker, so they are not suitable for validation purposes.
Thumbprint is a SHA1 of multiple properties of the certificate, including issuer, serial number, public key. That's probably OK, for now, and can't be changed by .NET because it's a Windows feature, but thumbprints are meant for reference, not security.
A better approach would be to compare the certificate Signature and hash, and put a minimum quality on the hash of SHA256 or higher. cert.SignatureAlgorithm.Value; will give you the algorithm as an OID, you can then new up an System.Security.Cryptography.Oid with that and get use the FriendlyName property to get the algorithm in text, but getting the actual signature isn't supported, you have to restore to 3rd parties like BouncyCastle. So that's probably out, because it seems silly to take a dependency for that.
Really this boils down to how you register the client certificates. What I would do is ask for the certificates (or have a registration process somewhere, like, say nuget has for signing certificates), put them into the X509Certificate2 class then create a SHA256 hash of the RawData property and add that to your allow list. Then do the same for incoming client certificates and compare the SHA256 of the rawdata from the inbound certificate against your allowed list. Of course now you have to cope with certificate expiration ...
This question relates to the use of SSL Pinning in a client app against a web api and certificate
expiry.
Scenario:
I own example.com and have a subdomain where an api is hosted, as such: api.example.com
I wish to use the api over SSL, so an SSL Certificate is created for the subdomain.
After the certificate has been acquired, I have:
A Public Certificate
A Intermediate Certificate
A Private Key
It's my understanding that I install these certificates on my webserver.
I then wish for my client app to connect to the api. To mitigate against man-in-the-middle style
attacks, I wish to use SSL Pinning, so that the client will only communicate with my api, not
someone spoofing it.
In order to pin in the client app, I have two choices, either pin against the public or intermediate
certificate.
Let's say I implement this.
What happens when the certificate on api.example.com expires?
It's my understanding that the client app would no longer work.
Do I need to regenerate a complete set of public/intermediate/private items again? and then
put a new public or intermediate certificate in the app?
Question:
I would still like the client app to work until the certificate on api.example.com was updated.
Of course, a new certificate can be put in the client app, but things like roll-out take time.
How can I handle this?
I've read that Google updates their certificate every month, but somehow manages to keep the public key the same: How to pin the Public key of a certificate on iOS
If that's possible, then the solution is to simply extract the public key from the server and check it against the locally stored public key...but how do Google do it?
Thanks
Chris
Note: I'm more familiar with browser to server pinning (HTTP Public Key Pinning - HPKP) rather than app to server pinning, but I presume the principal is the same. In HPKP the pinning policy is provided by the server as a HTTP header but understand this is often built into the app rather than read from the HTTP response. So read below answer with all that in mind:
Pinning is usually against the key not the cert and can be a multiple levels. So you've several choices:
Reuse the same key/crt to generate a new cert. Some (rightly in my opinion!) recommend generating a new key each time you renew your cert but this is complicated when you use pinning. So does pinning encourage poor security habits like key reuse?
Have several back up keys in your pinning policy and rotate them around on cert renewal discarding your oldest and adding a new one with plenty of time and updates to never be caught short. Personally I prefer to generate the key at cert renewal time rather than have some backups around which may or may have been compromised so I'm not a particular fan of this either. And how many backups should you have? E.g. If you need to reissue a cert because of compromise around renewal and also mess it up? So 2? 3? 100?
Pin further up. Say the first intermediate or the root CA cert. So any newly issued cert is still trusted (providing it's issued by same cert path) The downside of this is four fold: i) You still leave yourself open to miss-issued certs issued by that pinned cert (not a massive deal IMHO as you've still massively reduced your attack surface but still a concern to some people), ii) you cannot guarantee the client will use that intermediate cert as there are sometimes multiple valid paths. This second one is a much bigger deal. You'd think that providing the intermediate cert would guarantee this would be used but that's not the case (plenty of sha-1 examples of this). iii) There's no guarantee new cert will be issued by same intermediate or root (especially when technologies change like introduction of sha2), so to me this whole option is a non-starter iv) It ties you in to using same cert provider (perhaps not a big deal but I like the freedom to move). Not sure if apps support this feature natively anyway but browsers certainly do.
Renew in advance and do not use the new key until policy cache expires. For example if you have one year certs and a 30 day pinning policy then you can renew after 11 months, add the new key to the policy, then wait 30 days so you can be sure everyone will have picked up new policy or at least the old policy will have expired, then switch keys and certs. Depends on a short policy and potentially wastes a portion of that though (at least 30 days in this example), unless cert provider provides cert in advance starting on day after old policy expires. For an app, if pinning policy is hard coded into it, then this might involve the length of time it takes to push out an update.
Ultimately, because certs do require renewing, I'm not a big fan of pinning. I don't think making something that is subject to periodic renewal, semi-permanent is the right answer. And there are even some talk of pre-loading pinning policies in browsers which just makes me shudder.
Pinning provides assurance that a rogue CA is not issuing certs for your domain but how likely is that really compared to the hassle of pinning? Something like Certificate Transparency - or even report only pinning may be a better answer to that problem even if they don't actually stop that attack.
Finally locally installed roots (e.g. for antivirus scanners or corporate proxies), bypass pinning checks (on the browser at least) which again reduces its effectiveness in my eyes.
So think carefully before using pinning and make sure you understand all the consequences.
The mozilla developer site recommends to pin the certificate of the intermediate CA that signed the server certificate.
"it is recommended to place the pin on the intermediate certificate of the CA that issued the server certificate, to ease certificates renewals and rotations."
For more information on implementing and testing public key pinning you can refer Implementing and Testing HTTP Public Key Pinning (HPKP)
Your application can store multiple certificates in its pin list. The procedure for changing the cert would then be:
Some time before the certificate expires, release a new version of your app with a replacement cert in the pin list, as well as the original cert
when the old certificate expires, replace it on the server - the app should then still work as the new cert will already be in the pin list
Some time after the cert expires, release a new version of your app removing the old cert
Remember your users have to update the app before the old cert expires
it seams that, if using HTTPS protocol, packages transferred between browser and web server are all encrypted. And all the browser has to support its communication session with web server is so called certificates.
So I think it's clear that we can use the same certificates to decrypt packages that captured by Wireshark during the login of HTTPS sites.
I googled, and find some tutorials said the private key should be supplied, which i do think impossible and unpractical.
BTW. the following shell command get certificate from host , are there tools to yield the public key?
echo QUIT | openssl s_client -connect <site>:443 | sed -ne '/BEGIN CERT/,/END CERT/p'
Thanks in advance.
No, you cannot decrypt HTTPS/SSL sessions from a network capture, even if you do have the certificates. That is the whole point of Public Key Cryptography on which SSL is based.
What you have in your browser key-store is the certificates that will verify the validity of the public keys of the server. Said public keys are accessible, but they cannot be used to decrypt the session packets because the encryption algorithm is not symmetric.
You would need the private keys of the server in order to descrypt an SSL session and in normal situations it is quite hard to acquire those.
See also the Wikipedia article on TLS for more information.
EDIT:
I will add some more information in layman terms, mostly ripped off from the two links above, to make things a bit more clear.
Public Key Cryptography is based on asymmetric encryption algorithms. Those involve two keys, rather than one, a public key and a private key. Those two keys consist a key pair. Assuming a sufficiently strong algorithm, whatever is encrypted with the public key can only be encrypted with the private one and vice versa. The public key is widely accessible to "everyone" while the private key is stored securely and only used by its owner. How does this help?
The server has a key pair that consists of a world-readable public key and a securely stored (and inaccessible to anyone but the server itself) private key.
The client uses the server's public key to encrypt a rather long random key for a symmetric algorithm at the start of each encrypted session. That key is sent to the server.
Since the symmetric key is encrypted like this, it can only be decrypted using the server's private key. That means that it cannot be extracted from a captured network stream, and since it is used for the rest of the session, neither can any of the information that is transmitted later on.
The server uses its private key to retrieve the session symmetric key and all is well.
Is it? There is still one issue in the above scheme! How will the client get the server's public key? More specifically how does it know that it speaks with the server proper, and not some crook who managed to insert themselves in the middle (See Man In The Middle attack)?
The client cannot possibly know every single public key - there are millions of them. It will have to retrieve them from the servers and then somehow make sure they belong to the server they are interested in.
This is where another function of Public Key Cryptography comes in. Previously we used the public key to encrypt data so that only its intended destination could descrypt it. Now we
do the opposite: We use the private key to encrypt data so that it can only be decrypted with the public key. Essentially we sign the data so that if decrypts with the public key people will know the data came from the server. How does this help?
When the browser is installed it has a relatively small number of public keys (commonly known as certificates) pre-installed. Those belong to Certification Authorities (CA) that are entities (generally companies like Verisign, governments or even some Institutions) that are deemed trustworthy. The Certification Authorities use the corresponding private keys to sign other public keys available in the Internet and so on.
So when the browser contacts a server and receives its public key, that key should be signed with the private key from a certificate pair. That certificate pair would be likewise be signed by another and so on, until the browser comes up to a public key that was signed with the private key that corresponds to one of the Root Certificates that were preinstalled with it. You might want to read a previous answer of mine for more on Root Certificates, or just read the Wikipedia articles.
Since each public key was successively signed until we reached a trusted key, the client can now be certain that the server on the other end of the connection is indeed e.g. MyBank.com and not, say, some criminal's laptop in the next cafe table that is messing with the wireless connection.
While there have been weak SSL algorithms (hence the succession of SSL protocol versions), these days the attacks are generally targeted to the implementations:
Use specially crafted or malformed certificates to fool the browser (and its weak implementation) into thinking that a public key is signed by a trusted entity when it's really not.
Compromise the integrity of the client software (e.g. a virus) to capture the symmetric keys when they are generated. In most of those cases however, it is usually easier to just capture the interesting data as they are entered into the browser by e.g. capturing the keyboard strokes as the user types in their credit card number.
Compromise the server itself and steal the private key. While it's not as easy as targeting unsuspecting clients, it has happened and it has the potential to compromise a significantly larger number of encrypted sessions. The current Public Key Infrastructure (PKI) has a whole mechanism for the revocation and disabling of compromised or otherwise invalid keys.
The last attack can be defeated if the client sends a temporary public key of its own instead of a symmetric key and use an asymmetric algorithm for the whole session. That would make it impossible for an attacker to compromise past sessions by stealing the server's private key. This technique is the basis for ensuring Perfect Forward Secrecy, but unfortunately not all servers implement it yet due to compatibility or performance reasons.
thkala is spot on. You can, assuming you have MiTM, under common circumstances forward a self signed certificate to the victim for which you have the private key, then forward the requests by the victim to the destination server using the servers' real certificate. This will require the vicitm to accept a certificate warning though.
Another way of defeating Ssl is by stripping the ssl session, lookup sslstrip.
I would like to read the information a java application in firefox is sending to a website over an ssl connection.
I am using WireShark, and I believe that if I can somehow tell tell wireshark what encryption key firefox is using, then wireshark will be able to decrypt the ssl messages.
Then I will exactly what information this website is getting about my computer.
My apologies if the question is vague ... any pointers on where to start looking for clues would be appreciated.
Not really programming related.
However in order to do this you'll need the certificate for the site your application is connecting to, both the public and the private key parts - so if it's not a site you own then you'd not going to be able to do it. If you control the receiving web site then simply follow the instructions on the wireshark wiki.
Assuming that you're not trying to do this programmatically, but instead just want to view headers whilst debugging, you could use Charles:
http://www.charlesproxy.com/
There's a fair bit of information here about how to set it up to decrypt SSL traffic:
http://www.charlesproxy.com/documentation/using-charles/ssl-proxying/
The java application would encrypt all information with the server's public (SSL) certificate (at least as far as you are concerned). For all practical purposes the only way to decrypt this afterwards is to know the server's private key which you apparently do not have and therefore there is no way that you can decrypt it.
To answer your comment about whether to use your computer's private key:
If this is a "normal" SSL connection, the client (java app) will contact the server and receive its public key, verify it's valid (signed by a trusted CA) and then use it to negotiate a symmetric key that is used for encryption.
Public/Private keys work in a way that everything encrypted by one key can only be decrypted by the other - i.e. everything the Java app encrypts using the server's public key, can only be decrypted using the private key - which never leaves the server.
SSL/TLS supports client certificates, in which the Java app can have its own key pair and use its private key to sign the contents in order to verify the authenticity of itself. However even if the Java app does that (doubtful) it does not help as the data will still be encrypted so that only the server can decrypt it.
Background reading: http://en.wikipedia.org/wiki/Transport_Layer_Security and http://en.wikipedia.org/wiki/Public-key_cryptography
I work at company X and we want to engage in a B2B transaction with company Y. In doing so, Y is requiring client side authentication; they already provide server-side authentication - so this would be a mutual SSL transaction.
My understanding is that I simply need to provide my CA-signed cert as part of my client side HTTPS communication. In doing so, asymmetric cryptographic guarantees (i.e., public/private key technology) ensures that I am who I claim I am - in effect, it is not possible to impersonate me. (the root CA has ensured I am who I am, that is why they signed my cert, and it's possible to prove that I didn't "manufacture" the certificate).
Here's my question: is this all I need to provide company Y?
Alternatively, do I have to provide them with another key in advance, so that they can ensure I am not a rogue who happens to have "gotten a hold" of a root-signed certificate for me (company X)? It would seem that if one has to provide this extra key to all parties he wishes to engage with on the client side, it would seem to make client-side SSL not as scalable as server-side SSL. My guess is that it's not possible for one to "get a hold" of a client side cert; that the actual transmission of the client side cert is further encoded by some state of the transaction (which is not reverse-engineerable, feasibly).
Does this make sense and am I right or am I wrong? If I'm wrong, does Y in effect need to get an "extra" pre-communication key from every party that connects to it? (which they want to verify)?
Thanks.
===
Thanks for the responses below, at least the first two have been helpful so far (others may arrive later).
Let me talk in a bit more detail about my technical concern.
Suppose company Y attempts to "re-use" my client side cert to impersonate me in another client-side transaction with another company (say "Z"). Is this even possible? I am thinking - again, perhaps poorly stated - that some part of the transmission of the client side certificate prevents the entire key from being compromised, i.e., that is not technically feasible to "re-use" a client certificate received because you could not (feasibly) reverse engineer the communication which communicate the client cert.
If this is not the case, couldn't Y re-use the cert, impersonating X when communicating (client-side) to Z?
ps: I realize that security is never 100%, just trying to understand what is technically feasible here and what is not.
Thanks very much!
===
Further technical details, I appreciate any additional input very much - this has been very quite helpful.
From a layman's point of view, my concern is that when a client sends his client cert, what is he sending? Well, he has to encrypt that cert using his private key. He sends the ciphertext with the public key, and then a receiving party can use that public key to decrypt the private-key-encoded payload, right? That makes sense, but then I wonder -- what prevents someone from hearing that communication and simply re-using the private key encoded payload in a replay attack. Just replay the exact ones and zeroes sent.
Here's what I believe prevents that -- it can be found in the TLS RFC, in multiple places, but for example in F.1.1:
F.1.1. Authentication and key exchange
TLS supports three authentication modes: authentication of both
parties, server authentication with an unauthenticated client, and
total anonymity. Whenever the server is authenticated, the channel is
secure against man-in-the-middle attacks, but completely anonymous
sessions are inherently vulnerable to such attacks. Anonymous
servers cannot authenticate clients. If the server is authenticated,
its certificate message must provide a valid certificate chain
leading to an acceptable certificate authority. Similarly,
authenticated clients must supply an acceptable certificate to the
server. Each party is responsible for verifying that the other's
certificate is valid and has not expired or been revoked.
The general goal of the key exchange process is to create a
pre_master_secret known to the communicating parties and not to
attackers. The pre_master_secret will be used to generate the
master_secret (see Section 8.1). The master_secret is required to
generate the certificate verify and finished messages, encryption
keys, and MAC secrets (see Sections 7.4.8, 7.4.9 and 6.3). By sending
a correct finished message, parties thus prove that they know the
correct pre_master_secret.
I believe it's the randomization associated with the session that prevents these replay attacks.
Sound right or am I confusing things further?
As long as you keep the private key safe (and the CA keeps their signing key safe), "company Y" doesn't need any other information to authenticate you. In other words, they can be sure that a request really came from the subject named in the certificate.
However, this doesn't mean that you are authorized to do anything. In practice, most systems that use client certificates have an "out of band" process where you provide the "subject" distinguished name that is specified in the client certificate, and the system assigns some privileges to that name.
In fact, because of some practical limitations, some systems actually associate the privileges with the certificate itself (using the issuer's name and the certificate serial number). This means that if you get a new certificate, you might have to re-enroll it, even if it has the same subject name.
A certificate only assures a relying party you have a certain name. That party needs some additional mechanism to determine what you are allowed to do.
Unlike authentication mechanisms based on "secret" (symmetric) keys—e.g., passwords—a server only needs public information for asymmetric authentication. A private signing key should never be disclosed; it's certainly not necessary for client authentication.
With symmetric, password-based authentication, the client and server get access to the same string of bytes—the secret key. With public-key cryptography, only the public key of a key pair is disclosed. The corresponding private key is never disclosed, and no practical method for figuring out the private key from the public key has been discovered.
As long as you keep your private key safe, the server at company Y cannot forge requests that appear to come from you.
Client authentication replay attacks are defeated by requiring the client to digitally sign a message that includes a number randomly generated by the server for each handshake (this is the "random" member of the "ServerHello" message). If the packet used to authenticate the client in a previous session were re-used, a server will be unable to verify the signature, and won't authenticate the replay attack.
RFC 2246, Appendix F.1.1.2 might be a more helpful reference—especially the third paragraph:
When RSA is used for key exchange, clients are authenticated using
the certificate verify message (see Section 7.4.8). The client signs
a value derived from the master_secret and all preceding handshake
messages. These handshake messages include the server certificate,
which binds the signature to the server, and ServerHello.random,
which binds the signature to the current handshake process.
Your client-side certificate (or more precisely its private key), is only as secure as your company's online and/or physical security let it be.
For extremely secure relations (which typically do not have the requirement of scaling much), it may be acceptable that the provider of the service requires an extra element in the protocol which allows them to identify your site (and more often than not, to identify a particular computer or individual within the company, which is something client certs do not fully do.)
This of course brings the question: what is warranty that this extra bit of authentication device will be more securely held by your company? (as compared to the client-site certificate itself). The standard response for this is that these extra bits of security elements are typically non-standards, possibly associated with physical devices, machine IDs and such, and are therefore less easily transportable (and the know-how about these is less common: hackers know what RSA files to look for, and what they look like, what do they know of the genesis and usage of the KBD-4.hex file ?)
Extra question: Can Y make use of my client-side certificate elsewhere?
No they [normally] cannot! The integrity of this certificate lies in your safe keeping of its private key (and, yes, a similar safekeeping from the certificate providers...). Therefore, unless they are responsible for installing the said certificate, or unless their software on your client (if any) somehow "hacks" into certificate-related storage / files / system dlls, they should not be able to reuse the certificate. That is they cannot reuse the certificate any more easily (which is theoretically NP hard) than anyone that, say, would sniff the packets related to authentication as the client establishes a session with the Y site.
Extra questionS ;-)
- What is the nature of the client cert?
- Man-in-the-middle concerns...
Before getting to these, let's clear a few things up...
The question seems to imply TLS (Transport Layer Security) which is indeed a good protocol for this purpose, but for sake of understanding, the keys (public and private) from the certs (server's and client's) could well be used with alternative protocols. And also, TLS itself offers several different possible encryption algorithms for its support (one of the initial phases of a TLS session is for both parties to negotiate the set of algorithms they'll effectively use).
Also, what goes without saying... (also goes if you say it): the respective private keys are NEVER transmitted in any fashion, encoded or not. The confusion sometimes arise because after the authentication phase, the parties exchange a key (typically for a symmetric cipher) that is used in subsequent exchanges. This key is typically randomly generated, and of totally different nature than the RSA keys whether public or private!
In a simplified fashion, the client's certificate contains the following information:
- The Certificate Authority (CA aka issuer)
- The "owner" of the certificate (aka Subject)
- Validity date range
- the PUBLIC key of the certificate
In more detail, the certificates are typically found in an X.509 wrapper (? envelope), which contains additional fields such as version number, algorithm used, certificate ID, a certificate signature (very important to ensure that the certificate received wasn't tempered with). The X.509 also provide for optional attributes, and is also used for transmitting other types of certificate-related data (such as the CRL)
Therefore the certificate's content allow the recipient to:
- ensure the certificate itself was not tempered with
- ensure that the issuer of the certificate is one accepted by the recipient
- ensure that the certificate is valid/current and not revoked
- know the public key and its underlying size and algorithm
With regards to man-in-the-middle concerns, in particular the possibility of "re-playing" a possibly recorded packet exchange from a previous session.
The protocol uses variable, possibly random MACs (Message Authentication Codes) for that purpose. Essentially, during the negotiation phase, one of the parties (not sure which, may vary...) produces a random string of sorts and sends it to the other party. This random value is then used, as-is (or, typically, with some extra processing by an algorithm known by both parties) as part of the messages sent. It being encoded with the private key of teh sending party, if the the receiving party can decode it (with sender's public key) and recognize the (again variable) MAC, then it is proof that the sender is in possession of the private key of the certificate, and hence its identity is asserted. Because the MACs vary each time, pre-recorded sessions are of no help (for this simple purpose).