This is experimental.
message split allows you to send messages (passwords etc.) to another person without having the message decrypted on the server or in the email.
- msgsplit encrypts the message with a one-time-pad in Alices browser into a ciphertext and cryptographic-key
- sends the ciphertext to the server
- the server stores the ciphertext in a prefixed environment variable.
- returns the storage-key to Alice
- Alices browser creates a hyperlink with the storage-key as URL-query (''?'') and the cryptographic-key as URL-Fragment (''#'')
- Alices sends this link via email or messenger to Bob
- Bob opens the Link
- Bobs browser requests the ciphertext with the storage-key from server
- the server reads the ciphertext
- the server deletes the ciphertext
- now the server returns the ciphertext to Bobs Browser
- Bob decrypts the the message with ciphertext from the server and the cryptographic-key from the URL-Fragment.
There are several security concerns:
- The link get caught on his way, the offender could steal your message.
- If the server is compromised:
- the stored cipher is useless, but you could manipulate the javascript.
- if ciphers don't get deleted and the offender gets your mail, your message is disclosed
- The browser generates the key for the message, if your browsers Crypto.getRandomValues() is compromised, everything is worthless.
- Only the transmitted message is encrypted. The receiver is not authenticated. The first one who receives the link, has the message.
- brutforce all ciphertexts (
for i in {1..99999999999} ; do curl -s -X POST http://msg.exmple.net:8080/writeread --form "key=$1" ; done ;
): a ciphertext is still useless without the cryptographic-key.
Too be sure all ciphertexts stay out of every backup, log or any other datatrace, msgsplit needs the weakest persistent storage. There should be no external dependency filesystemmounts, database or object store.
So msgsplit uses environment variables to "store" ciphertexts. This is at the expense of usability: msgsplits data does not survive a reboot.
Only transmit messages that can get disclosed (inital passwords, etc). Do not use msgsplit for current used passwords. If the hyperlink gets stolen, this message is disclosed.
golang>1.20 is required
CGO_ENABLED=0 go build ./msgsplit.go
./msgsplit.go
Alternative:
Use plain image ghcr.io/klml/msgsplit:main
or with msgsplit-kubernetes.
Working demo, you can use it, but there is no safety guarantee!
Hostet on uberspace.de with supervisord as web backend, static files (index.html, css, js) as default apache and access log is disabled.
[msgsplit@erinome ~]$ cat ~/etc/services.d/msgsplit.ini
[program:msgsplit]
command=/home/msgsplit/msgsplit/msgsplit
autostart=yes
autorestart=yes
# `startsecs` is set by Uberspace monitoring team, to prevent a broken service from looping
startsecs=30
[msgsplit@erinome ~]$ supervisorctl status
msgsplit RUNNING pid 7138, uptime 0:09:34
[msgsplit@erinome ~]$ uberspace web backend list
/writeread http:8080 => OK, listening: PID 7138, /home/msgsplit/msgsplit/msgsplit
/ apache (default)
[msgsplit@erinome ~]$ uberspace web log access status
access log is disabled
There are better ways:
- ots.private.coffee uses also a hash parameter and an expiration date.
- horuspass.com/send uses also a hash parameter, an expiration date, but depends on
workers.cloudflare.com
. - pwpush.com Passwords automatically expire after a certain number of views and/or time has passed. Track who, what and when. But more complex.
- privatebin.info is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. But requires a database.
- and always openpgp.org
- windmemo.com was a service to send messages you could read only once.