Following up on last week’s post, it was decided that we would generate the private keys in the user’s browser, and then it would be uploaded to the server for the creation of the certificate. At first glance, this seemed to compromise security because by right the private key should not be anywhere else other than in the user’s possession. However, it would even have its own MIME type if it is not allowed to transmit the private keys somewhere else. Its transmission would require to have to have some form of security measures in place. In our case, it would be done using the HTTPS protocol, hence the connection to the server is encrypted. Moreover, the all the information regarding the user is stored on the server side, which will be used to fill in the relevant attributes of the Certificate Signing Request (CSR), and its creation requires the corresponding private key.
At the moment, this is how I planned the initial phase of the certificate installation procedure to be. The download URL would point to a REST endpoint of the server, and when the user clicks on that URL, the browser would prompt the user for any valid client certificate to send to the server. In that particular REST endpoint, we could handle for the case where the user does not provide any client certificate, and another case where they actually do provide a valid certificate. Note that the latter case would only happen when the user decides to renew their subscription early, i.e before their monthly renewal due date, hence this would mean that they would still be holding to the old valid client certificate. Such certificate should be revoked and the server provides a new certificate following the new subscription period. Anyhow, more details of that will be revealed when I actually start implementing that part.
But then, a problem unexpectedly arises. After creating the private key, it would still need to be exported in a format such that it could be transmitted to the server, like the PKCS#8 format. This is done using the
exportKey() method of the Web Crypto API. However, the Firefox browser that I am using for development does not support exporting ECDSA nor ECDH keys in PKCS#8 format. There’s a bug report on it since 4 years ago, but for reasons unknown, it has yet to be addressed by the Mozilla developers. It is frustrating, I must say. There is also another format for transmitting the private keys, which is JSON Web Keys (JWK). Apparently, there are no errors exporting the key in this format, but I have yet to figure out how it works. So all hope is not lost, I suppose. Tune in next week to find out.