Implementing Digitally signed data in a Web Application

browsercertificateSecurityweb-applications

I understand PKI well from a conceptual point of view – i.e. private keys/public keys – the math behind them, use of hash & encryption to sign a certificate, Digital Signing of Transactions or Documents etc. I have also worked on projects where openssl C libraries were used with certs for securing communication and authentication. I am also extremely familiar with openssl command line tools.

However, I have very little experience with webbased PKI projects & hence I am trying to design and code a personal project for this.

The requirements

(This is a learning project – This is never going to be used in a bank)

This is the website for a bank. All Internet Banking users are allowed use any signing certificate issued by a few known CAs (verisign, Thawte, entrust etc). The Bank is not responsible for procuring certificates for the user. The user logs into the bank site with his userid/password etc. He has access to most parts of his account. However, when the user wants to do a transaction – like transferring money to different account – the bank wants him to sign the transaction with a certificate.

The design

When user choses "Transfer" option – the website throws up a form where there are 3 entries – "Transfer To" account, the Amount of the transaction and a way for chosing a cert for doing the digital signing & do the signing.

I concatenate the "Transfer To" Account no & the amount plus a nonce and this is the string which will be signed and sent to the backend.

I have searched a lot but haven't been able to figure out how to achieve
– letting the user chose a cert
– do the signing.

I know how the user can add certs to his personal truststore on Windows. But how would I ask the browser to show him certs to chose from?

How does the signing get done – I really don't want to write crypto code in Javascript!!! So is the alternative having an ActiveX or a Java Applet? Is there a better way? Is there a way to ask the browser to use the cert and do the signing?

I have not decided on a platform/framework/language for now – so this question is rather generic.

I have searched a lot for this kind of info without luck – all I get is tutorials on digital signing, tutorials on how to enable PKI in Apache etc.

If someone feels my whole approach is wrong & there is a better way to do digital signing in a web-app – feel free to suggest those alternatives also.

Best Answer

I could be wrong about this, but as far as I know without resorting to implementing crypto in JavaScript or using some manner of plugin you cannot do exactly what you are attempting.

There is something close that is unpopular, but fairly well supported: Client Side Certificates

The general idea is that the client has a certificate in their keychain and that certificate is examined when they request a secured resource as part of the authorization sequence. After that point the communication proceeds over normal everyday SSL.

In your case if you were to have a web service that was behind SSL and a form that posts the transfer, transferTo and nonce and the service was configured appropriately to request client certificates the service would respond to the initial request with a request for credentials and the distinguished names of issuers it will accept. If the browser has more than one client certificate from that list it should prompt the user to select.

The rest of the conversation is just handled like any other SSL as I understand it, but you should then have access to the client certificate as part of the request object from the server end of things.

This is not exactly what you were asking for, but to my knowledge this is the closest you can get without doing something non-standard. The communication is secure because of the SSL, the user has proven they have a copy of the certificate and on the server end you can use the certificate to check that the user matches who they claim to be as an additional authentication factor. The message is not literally signed with the key, but the SSL communication channel the message traveled over was verified with the client key.

A stack overflow that discusses this further (see first answer & links):

https://stackoverflow.com/questions/1193013/ssl-client-cert-verification-optimisation

Examples of how you might set it up if you are in Microsoft land:

http://woloski.com/2012/08/04/securing-aspnet-webapi-with-clientcerts/

http://support.microsoft.com/kb/315588 (older versions)

Related Topic