Browser keygen is dead, long live browser key generation!

Now that Chrome has killed off the keygen tag, and assuming other Browsers follow suit, what options are there for generating private keys within the browser? Perhaps WebCrypto and JavaScript can come to the rescue?


With thanks to the excellent PKI.js and the useful examples, we've added an option to the PKI Cloud Free Online CA service which demos this approach. It's an easy way to try generating private keys in a browser, sending a certificate request to a remote CA, receiving the response and wrapping everything up into a PKCS#12.

Here's how to give it a go in five easy steps.

1. Register your free account:
https://testca.pkicloud.com/x_/testca/#register/

2. Create your first CA and add a new user. Make sure you select the user's Token Type as 'User Generated'.



3. After being redirected to the user's page, click on the 'Collection Link' button.



4. Change the Key Generation type to 'Browser Key Gen' and choose your key type and specification.



5. Copy the link into another browser window, enter the user's enrollment code and collect your PKCS#12!







If you have trouble or want to re-issue, use the 'renew/re-issue' link on the user's settings tab.




So what is actually happening?

On loading the connection page link, the browser uses PKI.js to generate a key. In the example the key settings are "keyalg=RSA&keyspec=2048".
Once this key is generated a Certificate Signing Request is immediately created.
On hitting 'submit', the page sends the CSR and enrollment code to the PKI Cloud API, the API validates the code, issues a certificate and sends it back.
With more help from PKI.js, the browser then rolls the key and certificate into a PKCS#12 file and downloads it.


How can I read the PKCS#12?

PKI.js explains in the examples page:

PKIjs, also only supports creation of AES-CBC and AES-GCM protected PKCS#12’s which will not be readable by Windows which only supports weak ciphers in PKCS#12 files.

You can parse the Password-Based Privacy Protection variant PKIjs creates using this command:

openssl pkcs12 -in pkijs_pkcs12.p12 -nomacver


Are all browsers supported?

The best chance of success is to use an up to date version of Chrome. IE, Edge and Safari are not working at the moment. Firefox will work as long as RSA keys are used.


Can keys be generated on smart cards or USB tokens?

No, only software tokens are supported.




Collect a certificate using SCEP

There are plenty of clients out there which use the Simple Certificate Enrollment Protocol to automate the enrollment of certificates. CISCO routers are one example, but it's also popular with Mobile Device Management software. Even iOS devices can talk SCEP.


PKI Cloud uses EJBCA's SCEP server, so let's try using this protocol to get a new certificate.
We'll use a free jscep client called jscep-cli-jdk6 (while using Oracle JDK 8).

Create a new certificate holder as described here, but make sure the Token Type is 'User Generated'.
We're making a certificate for the server 'james.example.com'.




Now let's build our client and get our certificate!

Check our Java Version.
 java -version  
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

Build the jscep client.
 git clone https://github.com/asyd/jscep-cli-jdk6.git  
 cd jscep-cli-jdk6  
 mvn assembly:assembly  




Make a new key and certificate request with OpenSSL.

 openssl req -new -newkey rsa:2048 -nodes -keyout key.pem -out req.pem -subj "/CN=james.example.com"  
Now use the SCEP client to send the certificate request and collect its certificate. Note the --dn argument refers to the user ID of the certificate holder, not the DN of the certificate request.
The --challenge option is the certificate holder's 'Enrollment code'.


  java -jar target/jscepcli-1.1-SNAPSHOT-exe.jar --ca-identifier "CN=James CA, O=James M, C=US" --challenge 1234 --csr-file req.pem --dn "CN=jamesca_scep" --key-file key.pem --url https://testca.pkicloud.com/testca/scep/pkiclient.exe --algorithm SHA256    
Received 1 CA certificate(s).
Received response containing 2 certificate(s).
Certificate issued

Have a look at your new certificate.
  openssl x509 -in cert.pem -text   
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 7343275386142428829 (0x65e88e0eaee38e9d)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=James M, CN=James CA
        Subject: CN=james.example.com


If you want to issue the certificate again, go to your certificate holder's settings and click the 're-issue' link next to their enrollment status. A user's status has to be 'New' or the SCEP client will not be permitted to enroll a new certificate.



Automate keystore generation using the PKI Cloud API

Let's generate a PKCS#12 (PFX) keystore using Curl commands!


After creating a free account, generating a CA and an API key, we will go to the Swagger page to test our key.

We're going to be using the /ca endpoint.
Visit:
https://testca.pkicloud.com/apidocs/ui/index.html#!/CaResource/resource_CaResource_getcas_GET



Enter your key in the Authorization field, using "Bearer <key>"



Click 'Try it out!' and see your response.


Curl

curl -X GET --header 'Accept: application/json' --header 'Authorization: Bearer eyAidHlwIjogIkpXVCIsICJhbGciOiAiUlMyNTYiIH0.eyAiYXV0aF90aW1lIjogMTQ4MDEwNzEyMSwgImV4cCI6IDE0ODAxMzExMjEsICJzdWIiOiAiamFtZXNtIiwgImF1ZCI6IFsgImNhYXBpIiBdLCAiaXNzIjogInRlc3RjYSIsICJpYXQiOiAxNDgwMTA3MTIxLCAianRpIjogIjEyMzNjMTQyLWFiNmUtNGY0NS05YjRjgfQ.PBzMWZvPKlQ2eniokxWwgnVRBa0oh8A8qRzECuZbmRKytYJ6hUUewIAHs7yHaMPutJNx5SbPo1cBlFF36_BURsvPU' 'https://testca.pkicloud.com/caapi/ca'

Request URL

https://testca.pkicloud.com/caapi/ca

Response Body

[
  {
    "id": 1069394785,
    "name": "CN=James CA, O=James M, C=US"
  }
]

Response Code

200



Now generate a new user for your CA. We'll just use Curl this time.
The user (certificate holder) has the ID 'jamesca_demo2' with (one time) password '1234'.
The certificate type is 'SSL Server'.

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: Bearer eyAidHlwIjogIkpXVCIsICJhbGciOiAiUlMyNTYiIH0.eyAiYXV0aF90aW1lIjogMTQ4MDEwNzEyMSwgImV4cCI6IDE0ODAxMzExMjEsICJzdWIiOiAiamFtZXNtIiwgImF1ZCI6IFsgImNhYXBpIiBdLCAiaXNzIjogInRlc3RjYSIsICJpYXQiOiAxNDgwMTA3MTIxLCAianRpIjogIjEyMzNjMTQyLWFiNmUtNGY0NS05YjRjLTM2YThniokxWwgn' -d '{
  "caName": "CN=James CA, O=James M, C=US",
  "endEntityProfileName": "SSL Server",
  "certificateProfileName": "SSL Server",
  "keyRecoverable": true,
  "password": "abcd",
  "subjectDN": "CN=james.example.com,O=JamesM,C=US",
  "tokenType": "P12",
  "username": "jamesca_demo2"
}' 'https://testca.pkicloud.com/caapi/users'


Use the user ID and password to get the keystore, saving the response in jamesca_demo2.p12.

curl -X POST --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/octet-stream' -d 'password=1234&username=jamesca_demo2' 'https://testca.pkicloud.com/caapi/pickup' > jamesca_demo2.p12

Check the contents of your new keystore.

$ keytool -v -list -keystore jamesca_demo2.p12 -storetype PKCS12

$ openssl pkcs12 -in jamesca_demo2.p12



Generate an API key

Automate user and keystore management with an API key. How to make your key.


First, click on the link in the top right to navigate to the API page.



Then view your keys.



Click on the create button to generate a new one.

Finally, click on the token (or the icon) to copy the token to the clipboard.




Now you have a key, try it out!

Create your first CA and user keystore

The first steps after creating a new account.


After creating your account and logging in, click the 'New CA' button.




Fill in the fields as you like and click create.






Your CA will appear in the list.





End-user or server certificates are given to users. Click on the icons to add or list the users associated with your CA. Click add, fill in the fields and then save.






If you select your new user and click 'New User Keystore' your browser will save a keystore with the type selected in 'Token Type'. By default, PKCS12.





Use the password to access your new keystore.

$ keytool -v -list -keystore jamesca_demo.p12 -storetype PKCS12

$ openssl pkcs12 -in jamesca_demo.p12


How to create a new account at PKI Cloud

PKI Cloud runs a free "PKI as a service" test system for creating and managing certificate authorities, end users and their certificates. Here's how to try it out.



Go to the registration page and complete the reCAPTCHA.





Enter a username and password. You don't need to enter any other details if you don't want to.




You should see your account has been successfully registered.






Go to the login page and sign in.




That's it! Now make your first CA and add some users.