This is a very common use case. For example, I want to share sensitive login credentials with other members of my team so that we can administer servers.
Plaintext must be encrypted, and then both the password and the ciphertext have to be transferred to the friendly party over the insecure channel that is the internet.
The catch? I don't want to have to guide my associate through (or burden myself with having to go through) installing PGP or generating a 2048bit RSA keypair and host an SFTP server or something like that.
That means the only option left is the web browser.
Here's my solution so far. Consider
onetimesecret.com to be a generalized web-accessible service that actually does what it promises to do. My question is, can this be further improved?
- Alice runs
cat /dev/urandom | base64, grabs some part of the stream, long enough to be a good password, and not too long for the next step
- Alice sends this string to Bob via https://onetimesecret.com/
- Alice waits for Bob to report that the string has been successfully retrieved. If we trust
onetimesecret.com, this means that only Alice and Bob are in possession of the string. If Bob reports that the link is dead and has been accessed, Alice throws away and generates a new password.
- Alice encrypts plaintext with the password that Bob has successfully received. For example, AES encryption using a 7z or RAR archive.
- Alice sends Bob another https://onetimesecret.com/ link with the contents. There is a bit of a flaw here, which is that the actual
onetimesecret.comservice doesnt appear to support file attachments. A workaround may be to Base64-encode the encrypted payload and send that. Or, less desirably, Alice can simply email it -- In this case, an adversary can obtain a copy of the encrypted file but would still need to decrypt it. Step 1 takes care of making this sufficiently hard.
The weakest link in this is likely to be step #3. I believe the correct terminology here is "Authentication".
The adversary's options are, as far as I can tell,
onetimesecret.comor have internal access to it (we handwave this and say it's fine, they're secure)
- break TLS or HTTPS. (we also handwave this and say it's fine, our OS is patched, our browser is patched)
- impersonate Bob until Alice performs step 5. (Alice demands Bob stay on the phone to verify step 3)
And I might be stating the obvious here but just to clarify, the need for all these 5 steps is to add a sort of "manual" handshake step independently, in an effort to prevent data leakage -- this still means we have to trust the
onetimesecret.com webservice to actually destroy the messages that we send to it that it promises are delivered only once.
The third item in the second list is the one relevant to the authentication part of our custom handshake. Traditional/standard secure authentication is not possible without the involvement of having extra steps to generate secure keys. I'm trying to streamline things to the point where they become practical. Which means not requiring users to be generating keys.