Store the client SSL certificate with out compromising security - ssl

I have stored Client SSL certificate in database as a file and its private key's password in a column (not using certificate store) for each web service that requires certificate.The reason I preferred this that I don't have to worry about user privilege to access the certificate if the code is moved to another server (Dev/QA/Prod). As certificate stored in centralized location, I don't have to install it in each machine. Moreover business people can upload certificate any time they want without intervening Developer and certificate will be different for QA and Production environment. Now my concern is that storing certificate in database compromise the security rather than storing it in certificate store?

From a security point of view, your strategy of placing the private keys AND the password in the database gives away rights to all the keys to the database admin, the software author AND the system admin.
Placing the private key's password on the system but not in the database only hands total control to the system admin and software author.
One other solution would be to store the private key in a hardware device (HSM) and only store references in your database. Your software would then use a hardware crypto API like PKCS#11 to perform the SSL client handshake crypto and your private keys would never be in system memory or on disk at all.

I guess you mean "I have stored Client SSL certificate in database as a file, its private key and its private key password". Maybe the X.509 certificate and its private key are in a single container, presumably in PKCS#12 format.
(Or do you just really want to store only the certificate? Storing just the certificate is fine, but why would you store the private key's password too.)
This isn't necessarily wrong, but you have to make sure access to this data-based is well protected.
In general, the private key is really that: private. Some certification authorities even mandate in their policies that no one other that the end-user may know the private key (at least with reasonable protection, e.g. within the browser or in a PKCS#12 file for which only they know the password).
This makes sense when using public and private keys.
I think you need to look carefully at all the angles of your design. It's not clear why you want to store the private keys in a database for the users to retrieve. It may make sense to store private keys in a central place, but this may also defeat the point of using client-certificate to authenticate (it really depends on the full picture and the degree of security you really want).
Storing all your users' private keys in a central place is probably not as secure as having each user use their own store, but it may be acceptable. Ultimately, it depends on the threats you may encounter.

Related

Is it possible to link a certificate to specific device in client certificate authentication?

Need to authenticate a server using certificate, I have used OpenSSL to generate certificate and it was able to authenticate with certificate by enabling client certificate authentication in IIS.
Now when I export the certificate from the device and tried to install it in the other device it was able to authenticate the server, is there any possible way to link or generate a certificate that will only work for the specific machine?
Yes - keep the private key private.
Moving a certificate by itself to another client won't let you authenticate as the owner of that certificate. You would have to move both the certificate and its corresponding private key.
There are generally two ways you can stop the private key being copied:
Use administrative controls to ensure nobody in your organisation copies the keys. This is usually in the form of an agreement between the certificate issuer and the entity named in the certificate, to the effect that "you shall not copy the private key!!". As you can imagine, depending on the scenario, this might not be that enforceable.
If the certificate is certifying a device, generate and store the private key in a hardware device that is a permanent fixture in that client device. A Trusted Platform Module is an example of a device fitted in most modern end-user devices for this purpose.
If the certificate is certifying a person, generate and store the private key in a hardware device that is issued to that person. A smart-card is an example of such a device. You would probably also need administrative controls here to ensure that the user doesn't share their card with others and that they keep any PINs or other authentication data private.
Note that attempting to certify something like the DNS name of the client device as as unique identifier doesn't work, as DNS, MAC addresses etc. can be spoofed.

If I want to limit access in SSL/DTLS to a certain group of servers, what is wrong with just comparing Base64/pem files?

Reading up on SSL certificates. There is plenty of material on verifying certificates, CA roots, etc. However, if I want to be certain that only a given
group of servers can be accessed, is there anything wrong with just keeping a cache of the Base64/pem format certs in a file and comparing them?
I have seen answers on the web that the cert will change according to when it was accessed, so I got the pem on an example server, www.yahoo.com, then stored it, accessed the same server and got another pem later, and they matched. I suspect that the cert will be as good as a fingerprint until expiration or the server changes to a new cert.
My idea is to show the decoded cert to the user, then store the base64 verion in a file/cache to form a list of "very trusted servers", or alternately let the user simply form his/her own list of such servers.
The other answer I have seen is to store and compare the decoded version, but this does not seem to me to be as secure as directly comparing the encoded cert.
Thanks for opinions.
If the certificates are validated during the handshake according your requirements, then you may use such a whitelist.
Using "trust-management" is in my opinion not more complex than such a whitelist. Especially, of all peers are controlled by the same organisation. You can create your own CA (even a offlineCA, may be you setup a organisation specific process to ensure, that the CA's private key is used compliant), and as good as you protect that CA's private key, you may trust that CA. So simply use that CA certificate as "only" trust to your TLS/DTLS setups on client and server, and sign all client and server certificates with that CA.

DDS Security certificate storage

I am currently developing using DDS with the security plugins enable.
When the application starts, it looks for the path to the CA certificate, Local certificate and private key and load them in memory for future usage.
Certificates containing the public keys are not sensitive as they are usually sent in clear and checked using the CA certificate. So an attacker has no need to get access to it. Is that correct?
However, on a Ubuntu filesystem, how can I protect the private key? The only way I see is to put the key as Read-Only only for a specific user that will run the application. But because of privilege escalation, this seems insecure.
Are there secure way to secure private keys on a filesystem ?
About the permissions_ca and Governance/Permissions documents, if those are updated by an attacker (which would create its own CA and sign new Governance/Permissions documents), then, can an application could have more permissions? Meaning that those documents should be secured on the filesystem?
Most of your questions are not specific to DDS Security, but are about general Public Key Infrastructure (PKI) mechanisms as leveraged by DDS Security.
Certificates containing the public keys are not sensitive as they are
usually sent in clear and checked using the CA certificate. So an
attacker has no need to get access to it. Is that correct?
Yes, that is correct. The built-in plugins as defined by the DDS Security specification use a PKI. The public key certificate does normally not contain any confidential information.
However, on a Ubuntu filesystem, how can I protect the private key?
Using "traditional" Unix permissions to allow only the owner of the file to access it is common practice. For example, SSH on Ubuntu by default stores private keys that way, in ~/.ssh. Additionally, the specification allows for encryption of the private key using a passphrase. That too is common practice.
Whether this is good enough for your scenario depends on your system's requirements. It is possible to integrate with existing, stronger key storage solutions like Windows certificate stores or macOS keychains by implementing customize security plugins. The pluggable architecture as defined in the spec was intended to allow for that, but the actual availability of such solutions depends on the DDS product that you are using.
About the permissions_ca and Governance/Permissions documents, if
those are updated by an attacker (which would create its own CA and
sign new Governance/Permissions documents), then, can an application
could have more permissions?
Both the Governance and Permissions documents have to be signed by a signing authority. Tampering with those files would break the signature verification and therefore would be detected by other Participants in the Domain.
All participants in the secured DDS Domain need to trust the same signing authority to make this mechanism work. For an attacker to successfully modify a Governance or Permissions document, it would have to have access to the private keys of the signing authority. Again, this is a common technique used in public key infrastructures similar to the public key certificate signing.
In spite of the tamper protection, it still makes sense to protect those files. The actual result of tampering or deletion of those files would be a denial of service, which is harmful as well.

Add RSA based encryption to WCF service without certificates

I am looking for a way to encrypt messages between client and server using the WCF. WCF offers a lot of built in security mechanisms to enrcypt traffic between client and server, but there seems to be nothing fitting my requirements.
I don't want to use certificates since they are too complicated, so don't suggest me to to use certificates please. I don't need confidentiality, so I though I'll go best using plain RSA.
I want real security, no hardcoded key or something. I was thinking about having a public/private keypair generated every time the server starts. Both keys will only be stored in RAM.
Then wen a client connects it should do exactly like SSL. Just as described here.
1.exchange some form of a private/public key pair; the server generates a key pair and keeps the private key to itself and shares the public key with the client (e.g. over a WCF message, for instance)
2.using that private/public key pair, exchange a common shared secret, e.g. an "encryption key" that will symmetrically encrypt your messages (and since it's symmetrical, the server can use the same key to decrypt the messages)
3.setup infrastructure on your client (e.g. a WCF extension called a behavior) to inspect the message before it goes out and encrypt it with your shared secret
That would be secure, wouldn't it?
Is there any existing solution to archive what I described? If not I'll create it on my own. Where do I start best? Which kind of WCF custom behaviour is the best to implement?
EDIT:
As this is NOT secure, I'll take the following approach:
When Installing the server component a new X509 certificate will be generated and automatially added to the cert store (of the server). The public part of this generated certificate will be dynamically included into the client setup. When running the client setup on the client machine the certificate will be installed into the trustet windows certificate store of the client.
So there's no extra work when installing the product and everything should be secure, just as we want it.
You've said you don't want to use certificates. I won't push certificate use on you, but one thing you are missing is that certificates serve a purpose.
A certificate proves that key you are negotiating an SSL connection with belongs to the entity you think it belongs to. If you have some way of ensuring this is the case without using certificates, by all means, use raw keys.
The problem is, in step 1:
1.exchange some form of a private/public key pair; the server generates a key pair and keeps the private key to itself and shares the public key with the client (e.g. over a WCF message, for instance)
How does the client know that the public key it received from the server wasn't intercepted by a man-in-the-middle and replaced with the MITM's key?
This is why certificates exist. If you don't want to use them, you have to come up with another way of solving this problem.
Do you have a small, well-known set of clients? Is it possible to preconfigure the server's public key on the client?
Alexandru Lungu has created an article on codeproject:
WCF Client Server Application with Custom Authentication, Authorization, Encryption and Compression
No, it would not be secure!
since there's no confidentiality, an attacker could do a men in the middle attack, and all the security is gone.
The only real secure way of encrypting messages between server and client IS to actually use digital certificates.
I'm sorry, the only two methods of providing secure communications are:
Use a public key infrastructure that includes a chain of trust relationships, a.k.a. certificates
or
Use a shared secret, a.k.a. a hardcoded key.
Nothing else addresses all of the known common attack vectors such as man-in-the-middle, replay attack, etc. That's the hard truth.
On the other hand I can offer you an alternative that may alleviate your problem somewhat: Use both.
Write a very, very simple web service whose only job is to generate symmetric keys. Publish this service via SSL. Require end user credential authentication in order to obtain a symmetric key.
Write the rest of your services without SSL but using the symmetric keys published via the first service.
That way your main app doesn't have to deal with the certificates.

Is it possible to decrypt Wireshark packages using web browser certificates?

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.