How it works

Supported Browsers/Environments

Only tested with the latest versions of Chrome and Firefox on windows 10 and Android(chrome only).

Setting Up Your Own Copy

You are strongly encouraged to use your own personal instance of this application. You can do it by deploying it on your local https web server.
Https is required by the webcrypto API, this application won't work when loaded over http or when using the file:/// protocol.
To install your own instance :
  1. Download the application package from Github.
  2. Copy the following files and folders into a folder on your web server:
    • google.html
    • img folder
    • css folder
    • js folder
  3. Obtain your own Google API key and client id. See https://developers.google.com/identity/sign-in/web/devconsole-project for more information.
  4. Edit js/simple-secure-app-configuration.js file and replace the default values with your client ID and API key. Save the file and that's all.
    If you use the default client and API id, your usage statistics will appear in the project owner's Google account.

Creating Keys

You can create new encryption and signing keys using the application. By default it will create an encryption/decryption pair (RSA-OAEP 2048 bits with SHA-256) and a signing/verification pair (RSASSA-PKCS1-v1_5 2048 bits with SHA-256). The same key pair is not used for signing/verification and encryption/decryption.
The application does not support PGP or similar and does not plan to support them in the future either.
The goal of this application is to provide simple and free end to end encryption and signing for any one.

A very rough summary of the key generation process is as follows:

  1. Generate new signing key pair using window.crypto.subtle.generateKey with RSASSA-PKCS1-v1_5 2048 & SHA-256, exportable=true, usages=sign, verify
  2. Export the private key from step 1 using window.crypto.subtle.exportKey in jwk format
  3. Export the public key from step 1 using window.crypto.subtle.exportKey in jwk format
  4. Generate new encryption/decryption key pair using window.crypto.subtle.generateKey with RSA-OAEP 2048 & SHA-256, exportable=true, usages=encrypt, decrypt
  5. Export the private key from step 3 using window.crypto.subtle.exportKey in jwk format
  6. Export the public key from step 3 using window.crypto.subtle.exportKey in jwk format
  7. Generate PBKDF2 cryptokey using a password entered by the user and calling window.crypto.subtle.importKey where exportable=false, usages=['deriveBits', 'deriveKey']
  8. Derive AES-CBC key using the PBKDF2 key from the previous step by calling window.crypto.subtle.deriveKey with the pbkdf2 key, using (number of iterations selected by the user + 100) iterations and hash=SHA-256
  9. Then derive the IV bits using the same PBKDF2 key by calling window.crypto.subtle.deriveBits using number of iterations selected by the user (note that it's +100 above, so there are 100 iterations between the IV and the key. So it should be good enough?) and hash=SHA-256. The salt for the deriveKey and deriveBits calls is also generated based on the selected number of iterations. (It's not random, it's just better than nothing)
  10. Create a json object which includes the exported jwk keys. stringify and base64 encode it
  11. window.crypto.subtle.encrypt the base64 encoded json string using the AES key and IV
  12. Base64 encode the output, add it to a json and store the file in Google Drive

Since the keys are stored in Google drive, an attacker would need to have access to both your Google account and the password you enter in this application.

Key storage

Your keys will be automatically uploaded to your Google Drive and they will be seamlessly available on any device you use. Private keys will be encrypted as described above.
You can move or even rename key files in your drive. They are stored and retrieved by using custom mime types. The following mime types are used for files stored in Google drive.

Adding contacts

You will obtain public key files from your contacts and import them using this application. Contacts' keys will also be stored in your Google Drive and they will be seamlessly available on all your devices. You can move or even rename key files in your drive. They are stored and retrieved by using custom mime types.
Contact keys will be signed by using your signing private key and the signature will be verified every time contact keys are used.
For example when you receive an email from Bob,
  1. The application will download Bob's public key file from your Google drive
  2. Verify the signature on the contact key file using your signing key (contact file will be signed by your key when you add the contact)
  3. Use Bob's key to verify the message signature if and only if the signature was verified in the previous step
This will prevent an attacker who has access to your Google drive to impersonate Bob by changing his key file in your Google drive.

Sending emails

Secure emails will be just regular emails with two additional attachments named simple-secure.message and simple-secure.signature. Email body, subject and headers will not be encrypted. Only the simple-secure.message attachment will contain a text part and attachments, all of which will be encrypted and signed.

You will be allowed to send secure emails to only contacts with a public key file in your Google drive. You can cc others but they won't be able to read the secure contents. Email encryption works as follows :
  1. A new random AES-CBC (128 bits) key will be generated (not a derived key) by calling window.crypto.subtle.generateKey
  2. A random initialization vector will be generated by calling window.crypto.getRandomValues
  3. Email body and attachments will be wrapped into a JSON object and stringified
  4. The string will be encrypted using the AES key and the initialization vector
  5. The AES key and the initialization vector will be encrypted by using public keys of each recipient (if you have 3 recipients, there will be 3 separate encrypted keys and IVs in the final package) An attacker who has access to the encrypted package will need to crack both the AES key and the IV to be able to decrypt the secure message.
  6. The final JSON object will include keys, IVs and the encrypted data
  7. The JSON object will be stringified and base64 encoded. This string will be attached to the email message as a file named simple-secure.message (with application/vnd.sozkan.simple-secure.message mime type).
  8. The base64 encoded string from the previous step will be signed by using your private key. And the signature will be attached to the email as a file named simple-secure.signature (with application/vnd.sozkan.simple-secure.signature mime type).
  9. The email will be sent using the Gmail REST API. (No other protocols will be used)

Receiving emails

The inbox page will show you a list of only the emails with a simple-secure.message attachment with application/vnd.sozkan.simple-secure.message mime type. You should continue to use the standard Gmail UI for anything else. (This is not a Gmail UI replacement)
  1. Emails with simple-secure.message attachments will be loaded using the Gmail REST API. (No other protocols will be used)
  2. When viewing an email, the application will download attachments (simple-secure.message and .signature files) using the Gmail REST API.
  3. simple-secure.message AES key and initialization vector for the current user will be located in simple-secure.message file and they will be decrypted using the current user's private key. (using window.crypto.subtle.decrypt with the current user's private key)
  4. Then simple-secure.message contents (email message text and attachments) will be decrypted using the AES key and the initialization vector. (using window.crypto.subtle.decrypt with the decrypted AES key and the initialization vector)
  5. Then the application will download sender's ('From' email header) public key contact file from your Google drive. (using Google drive API)
  6. Signature on the contact file will be verified using your signing private key. (using window.crypto.subtle.verify)
  7. If the signature on the contact file which includes the sender's public keys can be validated, then the sender's public key will be used to verify the signature in 'simple-secure.signature'. (using window.crypto.subtle.verify)
  8. A warning will be displayed if the signature can't be verified.

Google Drive

The application supports encrypting/decrypting files stored in Google Drive, using the same keys. Google Drive files can be encrypted for others using the same contact keys.

General Security Considerations