Saturday, February 14. 2015
Charles Engelke's last entry plays with WebCryptoAPI and X509 certificates. He parses a self-signed certificate, extracts its public key and signature and validates the latter (in a self-signed certificate the signature is signed by itself, by the private key associated with the certificate, so it is verified with its public key counterpart). In today's entry I decided to test it by myself but doing some minor changes.
A RSA key pair and a certificate were created using openssl.
$ openssl genrsa -des3 -out server.key 2048 $ openssl req -new -key server.key -out server.csr -x509 -subj "/C=ES/L=Madrid/O=Home/CN=TestSign" -days 7300
Finally I exported the key pair and the certificate to a PKCS12 file.
$ cat server.key server.csr > server.pem $ openssl pkcs12 -export -in server.pem -out server.pkcs12 -name testsign
In order to test that everything was working, a simple Sign.java class was implemented to perform a signature using the previously created key pair and then validating it.
$ java Sign "sample text" Singature:U72gD6t14VpCqKitUTEcBfa0TqXte/IPFLOF0wms+HfU+eTrEDQwZLZtZ0ju988JY/JsGElN9gxM apEKFnjiaS2O0qXMGrSSALgDKbGkSlvishFXysfYrWcYEn2/2mfuI3i9MYFqu2LgOTr1GC/jHqFm W0UW5NuRJCDaFEBbQBzedcuXuzKNcu18uFvUV2zJyHliuViU7L4m12vK9reFUTj7ghZBml62Lpxl g6CgjDdvBqy7tBh17k3OjHfINZiHLRb5ZA+3+YJRBAA2yOjUgaCWuGlwtqbLlWiuzxHF3XQxV/yh ad5Xw0RHdANLhiJixXuOTRbzEdLYHhBU7iL0Cw== Is signature OK? true
The class just loads the certificate and the key pair from the PKCS12 store and signs the text passed as the first argument. It shows the signature (in BASE64) and verifies it.
At this point I decided to change a bit what Charles was doing, instead of verifying the signature of the self-signed cert I was going to verify any signature (it is almost the same). So I collected all the JS code that Charles presented in the entry and prepared a static HTML page which is included at the end of the entry.
As a result of this little PoC the WebCryptoAPI needs two things in order to properly handle with the signature use-case:
The API should offer operations to handle keys in hardware tokens (PKCS#11 or similar).
The API should provide methods to manage certificates (Engelke's methods are wonderful but you know, this is an API, please do it nicely) and to access the internal (browser) user certificate store (maybe it could be just incorporated as another token). Obviously this is a risky operation and some confirmation from the user should be requested. But this is not a strange behavior, exactly the same thing is done when mic or camera are requested in WebRTC or when a site requires a user certificate to log the user in. With those methods the JS code could recover the internal certificate and the private and public key associated with it.
I think that, more or less, both requests are already in mind of the W3C group as the report of the workshop states. Hardware token are specially important because the second point depends on it (nowadays a personal certificate is always inside a secure hardware token, for example a lot of national eIDs work this way). The second point is exactly what people of Inventive Designers demanded in their presentation.
Finally in order to present a more workable PoC I prepared a little restful WS application that has the self-signed certificate inside and can sign and verify using WS in the server. The idea is you can sign any text and verify it using internal (using WebCryptoAPI in a capable browser) or external method (using WS and executing in the server).
The following video shows the little application. Using the firefox developer edition (iceweasel in Jessie is version 31.4 and does not support the API yet) I access the main page. First the certificate is requested to the server. Then some sample text is signed and verified externally. When the verification is internally done, the browser parses the certificate, obtains the public key and verifies the signature using the WebCryptoAPI. If the text is modified but not signed (the previous signature is still in the textarea) both validation fails.
Here you can download the maven project for the application.
This entry is a little test I did just to understand what the WebCryptoAPI can and cannot do. After I read the interesting entries about the same subject done by Charles Engelke I finally understood the idea behind the API. It presents methods for typical cryptographic operations in a basic raw mode. Until now there are no certificates or hardware tokens and, therefore, direct access to real key bits are needed. So, in my opinion, this API is just an entry point to be completed by a second one or an extension of this one.
Stay tuned for news about the WebCryptoAPI!
I agree with you completely that it would be good for the API to handle x.509 directly, and also to work with platform keys or hardware tokens outside the browser. Unfortunately, the Web Crypto Working Group has rejected both those ideas (see the mailing list archives at https://lists.w3.org/Archives/Public/public-webcrypto/).
Maybe they will eventually reconsider.
You are very kind writing here. All the webcryptoapi is becoming a bit crazy but I suppose that (at least) hardware tokens will be considered in the future. Everybody seems to agree on that (even in the work group).
Thanks for your thoughtful entries!