What's the simplest way to perform public key encryption?
Simplest for whom? I guess you mean for the person from the HR department. The easiest protocol that I see that can be implemented so that they only need to access the website twice without any additional actions on their part.
You would need to build a non-static site on your personal server where you are reasonably sure that the server provider is not looking on the server's hard drive.
Let's see the steps (implementation details are interwoven with the protocol):
Generate two cryptic URLs on your server and send the first URL to the HR person (recipient from now on). You ask the recipient to call you once they clicked the URL.
The recipient clicks the URL and a number of things happen:
The server checks whether this URL was requested before and will show an error if it was. In that case, this process must be initiated again.
If this is the first time that URL is called, the JavaScript generates a key pair (public+private).
The public key is sent to the server and stored there and the private key is stored in the localStorage in the recipients browser.
Additionally, the recipients browser generates a random string (called token), stores it in localStorage and sends it to the server where it is stored.
Now, the recipient calls you. At that time, you ask them whether there was an error. If there wasn't one, you need open the second cryptic URL that you generated in step 1. This cryptic URL is linked to the information that was received from the recipient in step 2 and contains a form where you can type in your SSN.
The SSN is encrypted with the stored public key and the ciphertext is published to a third cryptic URL that is based on the token from step 2.
You ask the recipient to click the link again and receives an error page, but this error page is quickly hidden, because there are additional values in the localStorage which means that it is a legitimate request. The recipient's browser does the following:
This protocol solves the issue that the SSN is never stored in cleartext on the server and if anybody would have clicked the link before or after the intended recipient, they would see nothing. Although, this might be still vulnerable to SSL interception by a malicious hoster and there are entry points for social engineering.
You could improve that a bit by using long-polling or web sockets if you don't want the recipient to click the URL a second time.
If you mean simplest for you, then you either need to compromise security or go to their offices in person.
You shouldn't use JSEncrypt for that. It would be hard to integrate it here. You should either go for forge (provides RSA and everything around it) or sjcl (provides ElGamal encryption through KEM which would need to be implemented together with AES-GCM; so also not really easy).
Don't send a SSN, don't enter it in a web browser. Call them, don't trust them calling you, make sure you are contacting the right company. Tell them the SSN over the phone. – zaph – 2017-03-24T22:18:27.883