Opmsg
opmsg message encryption
Install / Use
/learn @stealth/OpmsgREADME
opmsg
<p align="center"> <a href="https://github.com/c-skills/welcome"> <img src="https://github.com/c-skills/welcome/blob/master/logo.jpg"/> </a> </p>A gpg alternative
opmsg is a replacement for gpg which can encrypt/sign/verify your mails or create/verify detached signatures of local files. Even though the opmsg output looks similar, the concept is entirely different.
Features:
- Perfect Forward Secrecy (PFS) by means of ECDH or DH Kex
- native EC or RSA fallback if no (EC)DH keys left
- fully compliant to existing SMTP/IMAP/POP etc. standards; no need to touch any mail daemon/client/agent code
- signing messages is mandatory
- OTR-like deniable signatures if demanded
- easy creation and throw-away of ids
- support for 1:1 key bindings to auto-select source key per destination
- adds the possibility to (re-)route messages different from mail address to defeat meta data collection
- configurable, well-established hash and crypto algorithms and key lengths (RSA, DH, ECC, AES, Chacha)
- straight forward and open key storage, basically also managable via
cat,shred -uandlson the cmdline - seamless mutt integration
- Key format suitable for easy use with QR-codes
- optional cross-domain ECDH Kex
- PQC-safe operations mode if desired
opmsg builds fine with any of the OpenSSL, LibreSSL and BoringSSL libcrypto libraries. Building against BoringSSL is not recommended due to missing blowfish and ripemd algorithms.
You can use various transports with opmsg such as Mail or drops. Keys can be exchanged via mail, brainkeys or QR codes.
Build
opmsg requires the crypto primitives from OpenSSL. Just relax, its
not using the SSL/TLS proto, just the ciphering and hash algorithms.
For standard Linux distros, just type make.
The compilation requires a C++ compiler that supports -std=c++11.
This can be configured with e.g. make CXX=eg++ on OpenBSD.
This project supports both BN_GENCB_new and BN_GENCB for big number
generation. To disable BN_GENCB_new, set HAVE_BN_GENCB_NEW to false:
make DEFS=-DHAVE_BN_GENCB_NEW=0. So on OpenBSD, you would run
make CXX=eg++ DEFS=-DHAVE_BN_GENCB_NEW=0. On OSX you should install
your own OpenSSL, as Apple marks OpenSSL as deprecated in favor of their own
crypto libs. You may also set all these options in the Makefile.
It successfully builds on Linux, OSX, OpenBSD and probably a lot of others (Solaris, FreeBSD,...).
$ cd src
$ make
[...]
$ cp build/opmsg /usr/local/bin/
$ mkdir ~/.opmsg && touch ~/.opmsg/config
$ opmsg
opmsg: version=1.84 (C) 2021 Sebastian Krahmer: https://github.com/stealth/opmsg
Usage: opmsg [--confdir dir] [--native] [--encrypt dst-ID] [--decrypt] [--sign]
[--verify file] <--persona ID> [--import] [--list] [--listpgp]
[--short] [--long] [--split] [--new(ec)p] [--newdhp] [--brainkey1/2]
[--salt1/2 slt] [--calgo name] [--phash name [--name name] [--in infile]
[--out outfile] [--link target id] [--deniable] [--burn]
--confdir, -c (must come first) defaults to ~/.opmsg
--native, -R EC/RSA override (dont use existing (EC)DH keys)
--encrypt, -E recipients persona hex id (-i to -o, needs -P)
--decrypt, -D decrypt --in to --out
--sign, -S create detached signature file from -i via -P
--verify, -V vrfy hash contained in detached file against -i
--persona, -P your persona hex id as used for signing
--import, -I import new persona from --in
--list, -l list all personas
--listpgp, -L list personas in PGP format (for mutt etc.)
--short short view of hex ids
--long long view of hex ids
--split split view of hex ids
--newp, -N create new RSA persona (should add --name)
--newecp create new EC persona (should add --name)
--deniable when create/import personas, do it deniable
--link link (your) --persona as default src to this
target id
--newdhp create new DHparams for persona (rarely needed)
--brainkey1/2 use secret to derive deniable persona keys
--salt1/2 optional: use salt when when using brainkeys
--calgo, -C use this algo for encryption
--phash, -p use this hash algo for hashing personas
--in, -i input file (stdin)
--out, -o output file (stdout)
--name, -n use this name for newly created personas
--burn (!dangerous!) burn private (EC)DH key after
decryption to achieve 'full' PFS
If you want to use additional features, such as from opmux (opmsg/gpg auto forward) or opcoin
(using bitcoin network as a web-of-trust), also type make contrib. Contrib tools are
documented in README2.md. You may also want to check
opmsg-qr later on, to im/export opmsg
personas via QR codes, once you have set up your working environment.
Personas
The key concept of opmsg is the use of personas. Personas are an identity with either an EC or RSA key bound to it. Communication happens between two personas (which could be the same) which are uniquely identified by the hashsum of their EC/RSA keys:
$ opmsg --newp --name stealth
opmsg: version=1.2 -- (C) 2015 opmsg-team: https://github.com/stealth/opmsg
opmsg: creating new persona
.......[...].........................o..o..o..o..o..oO
opmsg: Successfully generated persona (RSA + DHparams) with id
opmsg: 1cb7992f96663853 1d33e59e83cd0542 95fb8016e5d9e35f b409630694571aba
opmsg: Tell your remote peer to add the following RSA pubkey like this:
opmsg: opmsg --import --phash sha256 --name stealth
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4Xds/bPlkdqA9VhDBOIEV/Dc9
4EfL5aPBOQAdTIaZKE69SJdwakFhqOY1PeaeGRDcGTVNLBQ1Udgbc2YCgQh1X5Dn
veRIGJoGfqWC7zeq/mx6yRer3PTUOA0gr30Uu7IO128fVDxNLYYUuvzhzcdysZAa
WkmRflKuaCEMQ3RjcQIDAQAB
-----END PUBLIC KEY-----
opmsg: Check (by phone, otr, twitter, id-selfie etc.) that above id matches
opmsg: the import message from your peer.
opmsg: AFTER THAT, you can go ahead, safely exchanging op-messages.
opmsg: SUCCESS.
This is pretty self-explaining. A new persona with name stealth is
created. The public RSA key of this persona has to be imported by
the remote peer that you want to opmsg-mail with via
opmsg --import --phash sha256 --name stealth
just as hinted above. After pasting the public key of your communication peer
into above commandline - once it told you to do so - you will be given the persona ID,
that consists of the hashsum (sha256 in this case) of the public key. ID's
may be presented to you in --short, --long, or --split (default) form,
and will be auto-detected in either form as you pass it to the command line.
opmsg does not rely on a web-of-trust which in fact never really worked. Rather, due to ubiquious messenging, its much simpler today to verify the hashsum of the persona via additional communication paths. E.g. if you send the pubkey via plain mail, use SMS and twitter to distribute the hash, or send a picture/selfie with the hash and something that uniquely identifies you. Using two additional communication paths, which are unrelated to the path that you sent the key along, you have a high degree of trust. Side-note: If you want to stay anonymous, do not send selfies with your persona id and dont use communication paths that can be mapped to you.
By default sha256 is used to hash the pubkey blob but you may also specify ripemd160
or sha512. Whichever you choose, its important that your peer knows
about it during import, because you will be referenced with this hex hash value
(your persona ID) in future.
The private part of the keys which are stored inside ~/.opmsg
are NOT encrypted. It is believed that once someone gained access
to your account, its all lost anyway (except for PFS as explained later),
so a passpharse just add a wrong feeling of security here. Keep
your account/box unpwned! Otherwise end2end encryption makes little
sense.
opmsg encourages users for easy persona creation and throwaway.
The directory structure below ~/.opmsg is easy and straight
forward. It just maps the hex ids of the personas and (EC)DH keys
to directories and can in fact be edited by hand.
Creation of RSA personas might take some time. Not just an RSA key is generated in that case - which is not very time consuming - but also DH parameters (2048bit by default) that are used to implement PFS in later messenging (see later chapter).
In order to speed up persona generation and to encourage use- and throwaway
and per-project personas, EC support was added to opmsg as of version=1.5.
Instead of --newp you would just use --newecp and everything else is the
same. opmsg will pick the right crypto transparently to you. No need to add
any further switches for encryption or alike. EC personas use the brainpool curves
(RFC 5639). The NIST curve secp521r1 may also be used as a fallback if your
libcrypto is outdated, but its recommended to use the brainpool curves which
dont keep any secrets about how their group parameters were selected.
Also see the chapter about cross-domain ECDH down below.
Persona linking
Although this step is not strictly necessary, it is recommended. As personas are easily
created, you can (should) create a dedicated persona for each of your "projects" or
contacts. That is, if you have 7 communication partners/peers, you should have
created 7 personas; one EC/RSA key for each of them. To handle that easily with your
mailer (see later for MUA integration), you should add a proper --name, describing your
id. If you are using email addresses along with names, use the format of --name 'da name <name@address>'
so that your MUA can easily pick a list of candidates for you.
Additionally, you should --link your source persona (each of the 7 you created)
to the particular destination persona that you wish to communicate with using this source id:
$ opmsg --link b3c32d47dc8b58a6 --persona 1cb
