{"id":13471104,"url":"https://github.com/stealth/opmsg","last_synced_at":"2025-04-04T19:09:36.947Z","repository":{"id":31646738,"uuid":"35212014","full_name":"stealth/opmsg","owner":"stealth","description":"opmsg message encryption","archived":false,"fork":false,"pushed_at":"2023-03-02T09:55:20.000Z","size":694,"stargazers_count":755,"open_issues_count":2,"forks_count":40,"subscribers_count":35,"default_branch":"master","last_synced_at":"2025-03-28T18:09:19.365Z","etag":null,"topics":["anti-censorship","censorship-circumvention","cryptography","dh","elliptic-curves","encryption","end-to-end-encryption","gpg","message-encryption","perfect-forward-secrecy","pgp","privacy"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stealth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2015-05-07T09:46:02.000Z","updated_at":"2025-03-23T16:36:23.000Z","dependencies_parsed_at":"2024-01-07T09:33:09.467Z","dependency_job_id":"931e6969-52a4-424c-b6be-e538d6610b78","html_url":"https://github.com/stealth/opmsg","commit_stats":{"total_commits":173,"total_committers":1,"mean_commits":173.0,"dds":0.0,"last_synced_commit":"e1f06fde202e4f55ad60b6c6cc96115cff63cd44"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Fopmsg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Fopmsg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Fopmsg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Fopmsg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stealth","download_url":"https://codeload.github.com/stealth/opmsg/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247234921,"owners_count":20905854,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anti-censorship","censorship-circumvention","cryptography","dh","elliptic-curves","encryption","end-to-end-encryption","gpg","message-encryption","perfect-forward-secrecy","pgp","privacy"],"created_at":"2024-07-31T16:00:39.825Z","updated_at":"2025-04-04T19:09:36.923Z","avatar_url":"https://github.com/stealth.png","language":"C++","readme":"opmsg\n=====\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/c-skills/welcome\"\u003e\n\u003cimg src=\"https://github.com/c-skills/welcome/blob/master/logo.jpg\"/\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n\nA gpg alternative\n-----------------\n\n_opmsg_ is a replacement for _gpg_ which can encrypt/sign/verify\nyour mails or create/verify detached signatures of local files.\nEven though the _opmsg_ output looks similar, the concept is entirely\ndifferent.\n\nFeatures:\n\n* Perfect Forward Secrecy (PFS) by means of ECDH or DH Kex\n* native EC or RSA fallback if no (EC)DH keys left\n* fully compliant to existing SMTP/IMAP/POP etc. standards;\n  no need to touch any mail daemon/client/agent code\n* signing messages is mandatory\n* OTR-like deniable signatures if demanded\n* easy creation and throw-away of ids\n* support for 1:1 key bindings to auto-select source key per destination\n* adds the possibility to (re-)route messages different\n  from mail address to defeat meta data collection\n* configurable, well-established hash and crypto algorithms\n  and key lengths (RSA, DH, ECC, AES, Chacha)\n* straight forward and open key storage, basically also managable via\n  `cat`, `shred -u` and `ls` on the cmdline\n* seamless mutt integration\n* Key format suitable for easy use with QR-codes\n* optional cross-domain ECDH Kex\n* PQC-safe operations mode if desired\n\n\n_opmsg_ builds fine with any of the OpenSSL, LibreSSL and BoringSSL libcrypto libraries.\nBuilding against BoringSSL is not recommended due to missing blowfish and ripemd algorithms.\n\nYou can use various transports with _opmsg_ such as Mail or [drops](https://github.com/stealth/drops).\nKeys can be exchanged via mail, brainkeys or [QR codes](https://github.com/stealth/opmsg-qr).\n\nBuild\n-----\n\n_opmsg_ requires the crypto primitives from _OpenSSL_. Just relax, its\nnot using the SSL/TLS proto, just the ciphering and hash algorithms.\nFor standard _Linux_ distros, just type `make`.\n\nThe compilation requires a C++ compiler that supports `-std=c++11`.\nThis can be configured with e.g. `make CXX=eg++` on _OpenBSD_.\n\nThis project supports both `BN_GENCB_new` and `BN_GENCB` for big number\ngeneration. To disable `BN_GENCB_new`, set `HAVE_BN_GENCB_NEW` to false:\n`make DEFS=-DHAVE_BN_GENCB_NEW=0`. So on _OpenBSD_, you would run\n`make CXX=eg++ DEFS=-DHAVE_BN_GENCB_NEW=0`. On _OSX_ you should install\nyour own _OpenSSL_, as Apple marks _OpenSSL_ as deprecated in favor of their own\ncrypto libs. You may also set all these options in the `Makefile`.\n\nIt successfully builds on _Linux_, _OSX_, _OpenBSD_ and probably a lot of others\n(_Solaris_, _FreeBSD_,...).\n\n\n```\n$ cd src\n$ make\n[...]\n$ cp build/opmsg /usr/local/bin/\n$ mkdir ~/.opmsg \u0026\u0026 touch ~/.opmsg/config\n$ opmsg\n\nopmsg: version=1.84 (C) 2021 Sebastian Krahmer: https://github.com/stealth/opmsg\n\n\nUsage: opmsg [--confdir dir] [--native] [--encrypt dst-ID] [--decrypt] [--sign]\n\t[--verify file] \u003c--persona ID\u003e [--import] [--list] [--listpgp]\n\t[--short] [--long] [--split] [--new(ec)p] [--newdhp] [--brainkey1/2]\n\t[--salt1/2 slt] [--calgo name] [--phash name [--name name] [--in infile]\n\t[--out outfile] [--link target id] [--deniable] [--burn]\n\n\t--confdir,\t-c\t(must come first) defaults to ~/.opmsg\n\t--native,\t-R\tEC/RSA override (dont use existing (EC)DH keys)\n\t--encrypt,\t-E\trecipients persona hex id (-i to -o, needs -P)\n\t--decrypt,\t-D\tdecrypt --in to --out\n\t--sign,\t\t-S\tcreate detached signature file from -i via -P\n\t--verify,\t-V\tvrfy hash contained in detached file against -i\n\t--persona,\t-P\tyour persona hex id as used for signing\n\t--import,\t-I\timport new persona from --in\n\t--list,\t\t-l\tlist all personas\n\t--listpgp,\t-L\tlist personas in PGP format (for mutt etc.)\n\t--short\t\t\tshort view of hex ids\n\t--long\t\t\tlong view of hex ids\n\t--split\t\t\tsplit view of hex ids\n\t--newp,\t\t-N\tcreate new RSA persona (should add --name)\n\t--newecp\t\tcreate new EC persona (should add --name)\n\t--deniable\t\twhen create/import personas, do it deniable\n\t--link\t\t\tlink (your) --persona as default src to this\n\t\t\t\ttarget id\n\t--newdhp\t\tcreate new DHparams for persona (rarely needed)\n\t--brainkey1/2\t\tuse secret to derive deniable persona keys\n\t--salt1/2\t\toptional: use salt when when using brainkeys\n\t--calgo,\t-C\tuse this algo for encryption\n\t--phash,\t-p\tuse this hash algo for hashing personas\n\t--in,\t\t-i\tinput file (stdin)\n\t--out,\t\t-o\toutput file (stdout)\n\t--name,\t\t-n\tuse this name for newly created personas\n\t--burn\t\t\t(!dangerous!) burn private (EC)DH key after\n\t\t\t\tdecryption to achieve 'full' PFS\n```\n\nIf you want to use additional features, such as from `opmux` (opmsg/gpg auto forward) or `opcoin`\n(using bitcoin network as a web-of-trust), also type `make contrib`. Contrib tools are\ndocumented in README2.md. You may also want to check\n[opmsg-qr](https://github.com/stealth/opmsg-qr) later on, to im/export `opmsg`\npersonas via QR codes, once you have set up your working environment.\n\nPersonas\n--------\n\nThe key concept of _opmsg_ is the use of personas. Personas are\nan identity with either an EC or RSA key bound to it. Communication happens between\ntwo personas (which could be the same) which are uniquely identified\nby the hashsum of their EC/RSA keys:\n\n```\n$ opmsg --newp --name stealth\n\nopmsg: version=1.2 -- (C) 2015 opmsg-team: https://github.com/stealth/opmsg\n\nopmsg: creating new persona\n\n.......[...].........................o..o..o..o..o..oO\n\nopmsg: Successfully generated persona (RSA + DHparams) with id\nopmsg: 1cb7992f96663853 1d33e59e83cd0542 95fb8016e5d9e35f b409630694571aba\nopmsg: Tell your remote peer to add the following RSA pubkey like this:\nopmsg: opmsg --import --phash sha256 --name stealth\n\n-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4Xds/bPlkdqA9VhDBOIEV/Dc9\n4EfL5aPBOQAdTIaZKE69SJdwakFhqOY1PeaeGRDcGTVNLBQ1Udgbc2YCgQh1X5Dn\nveRIGJoGfqWC7zeq/mx6yRer3PTUOA0gr30Uu7IO128fVDxNLYYUuvzhzcdysZAa\nWkmRflKuaCEMQ3RjcQIDAQAB\n-----END PUBLIC KEY-----\n\nopmsg: Check (by phone, otr, twitter, id-selfie etc.) that above id matches\nopmsg: the import message from your peer.\nopmsg: AFTER THAT, you can go ahead, safely exchanging op-messages.\n\nopmsg: SUCCESS.\n```\n\nThis is pretty self-explaining. A new persona with name `stealth` is\ncreated. The public RSA key of this persona has to be imported by\nthe remote peer that you want to opmsg-mail with via\n\n```\nopmsg --import --phash sha256 --name stealth\n```\n\njust as hinted above. After pasting the public key of your communication peer\ninto above commandline - once it told you to do so - you will be given the persona ID,\nthat consists of the hashsum (sha256 in this case) of the public key. ID's\nmay be presented to you in `--short`, `--long`, or `--split` (default) form,\nand will be auto-detected in either form as you pass it to the command line.\n\n\n_opmsg_ does not rely on a web-of-trust which in fact never really\nworked. Rather, due to ubiquious messenging, its much simpler today\nto verify the hashsum of the persona via **additional** communication\npaths. E.g. if you send the pubkey via plain mail, use SMS **and** twitter\nto distribute the hash, or send a picture/selfie with the hash\nand something that uniquely identifies you. Using **two additional**\ncommunication paths, which are unrelated to the path that\nyou sent the key along, you have a high degree of trust.\n_Side-note: If you want to stay anonymous, do not send selfies\nwith your persona id and dont use communication paths that can\nbe mapped to you._\n\nBy default `sha256` is used to hash the pubkey blob but you may also specify `ripemd160`\nor `sha512`. Whichever you choose, its important that your peer knows\nabout it during import, because you will be referenced with this hex hash value\n(your persona ID) in future.\n\nThe private part of the keys which are stored inside `~/.opmsg`\nare NOT encrypted. It is believed that once someone gained access\nto your account, its all lost anyway (except for PFS as explained later),\nso a passpharse just add a wrong feeling of security here. Keep\nyour account/box unpwned! Otherwise end2end encryption makes little\nsense.\n\n_opmsg_ encourages users for easy persona creation and throwaway.\nThe directory structure below `~/.opmsg` is easy and straight\nforward. It just maps the hex ids of the personas and (EC)DH keys\nto directories and can in fact be edited by hand.\n\nCreation of RSA personas might take some time. Not just an RSA key\nis generated in that case - which is not very time consuming - but also DH\nparameters (2048bit by default) that are used to implement PFS\nin later messenging (see later chapter).\n\nIn order to speed up persona generation and to encourage use- and throwaway\nand per-project personas, EC support was added to _opmsg_ as of `version=1.5`.\nInstead of `--newp` you would just use `--newecp` and everything else is the\nsame. `opmsg` will pick the right crypto transparently to you. No need to add\nany further switches for encryption or alike. EC personas use the brainpool curves\n(RFC 5639). The NIST curve `secp521r1` may also be used as a fallback if your\nlibcrypto is outdated, but its recommended to use the brainpool curves which\ndont keep any secrets about how their group parameters were selected.\nAlso see the chapter about cross-domain ECDH down below.\n\n\nPersona linking\n---------------\n\nAlthough this step is not strictly necessary, **it is recommended**. As personas are easily\ncreated, you can (should) create a dedicated persona for each of your \"projects\" or\ncontacts. That is, if you have 7 communication partners/peers, you should have\ncreated 7 personas; one EC/RSA key for each of them. To handle that easily with your\nmailer (see later for MUA integration), you should add a proper `--name`, describing your\nid. If you are using email addresses along with names, use the format of `--name 'da name \u003cname@address\u003e'`\nso that your MUA can easily pick a list of candidates for you.\n\nAdditionally, you should `--link` your source persona (each of the 7 you created)\nto the particular destination persona that you wish to communicate with using this source id:\n\n```\n$ opmsg --link b3c32d47dc8b58a6 --persona 1cb7992f96663853\n\nopmsg: version=1.2 -- (C) 2015 opmsg-team: https://github.com/stealth/opmsg\n\nopmsg: linking personas\nopmsg: SUCCESS.\n\n```\n\nThis is to avoid the need to specify `--persona` each time you\nsend a message to a different target persona, changing your local\nid back and forth inside the config file or at the command line.\nAbove command says, that each time you send an opmsg to `b3c32d47dc8b58a6`,\nthe keying material from your local id `1cb7992f96663853` is used. To unlink\nyour id from `b3c32d47dc8b58a6`, remove the `srclink` file inside this personas\ndirectory.\n\nIf no link is found for a persona, the config file and given\n`--persona` argument is evaluated. Command line arguments override the config file settings.\n\nGiven proper mail provider support (e.g. inboxes are created on the fly\nfor addresses like hexid@example.com), the global surveillance meta graph would\njust contain pairs of communication partners. No clusters, just islands\nof 1:1 mappings.\n\n\nDeniable personas\n-----------------\n\nThere may be valid scenarios where you dont want your communication peer to have a way to proof\nthat you wrote a certain message. Since op messages are always signed with your persona\nkey, peer could proof that you were expressing illegal thoughts. So you want deniable messages\nthat are still integrity protected. The OTR protocol is handling this by sharing the public as\nwell as the private key for a dedicated communication session between both peers.\n\n_opmsg_ allows to do the same. It requires an additional communication step with a peer\nthat you already imported once and which you suspect to do such back stabbing.\n(Generally speaking its wise to assume that case.)\n\nIt is recommended to use EC personas for that purpose, as its faster. Just add `--deniable`\nswitch on the commandline when creating or importing this deniable persona as well\nas a `--name` that reflects deniability for you.\nThis will print or import the private key half of the persona and link it to itself.\n\nAs this new persona is linked to itself, whenever you send something to the peer the\nsigning key is shared with _that_ peer. You can always deny that you sent this message\nas your peer could also have signed it (`src-id` and `dst-id` inside the message are the same).\n**Only exchange deniable persona keys across an existing secure (encrypted) channel as it\ncontains private keying material.\nDo not share any key material of this dedicated new EC persona to anyone else. Its only for\nthis dedicated, deniable, communication peer.**\n\nOnce a deniable peer is established, you may use it as often and as long as you wish\nand as within normal operation.\nDeniable op messages are integrity protected and feature all crypto benefits.\n\nOf course for this to work you also want to have fully encrypted your disk to leave no\nforensic artifacts and dont want to cite your peer in reply-messages as this proofs\nthat you were able to decrypt a mail from your peer, e.g. you are hold of a certain\nprivate session key (`kex-id`). Thats a common mistake people make who dont sign\ntheir emails and think everything is deniable.\n\n\nBrainkey Personas\n-----------------\n\nBrainkey personas are deniable personas whose key was not generated via RNG\ninput, but which are derived from a passphrase. They are very similar to the\nconcept of BTC brainwallets. When generating brainkey personas, the commandline\nshould be as explicit as possible in order to have matching personas on both sides\ndespite potentially different config-file settings for EC curves or hash algos:\n\n```\n$ opmsg --name=nobrainer --deniable --salt1 1234 --brainkey1 --newecp=secp521r1 --phash=sha256\n\nopmsg: version=1.80 (C) 2021 Sebastian Krahmer: https://github.com/stealth/opmsg\n\nopmsg: Enter the brainkey, 16 chars minimum (echoed): mysupersecretnobodyknows\nopmsg: creating new EC persona (curve secp521r1)\n\n\n\nopmsg: Successfully generated persona with id\nopmsg: a6da74f688c375d8 96858709ffd1a25f d42e6523bb89d0f2 45cfe554cf7b4e7c\nopmsg: You created a deniable persona.\nopmsg: Your persona key was derived from a brainkey. No need to exchange keys\nopmsg: with your peer. Your peer just needs to execute the same command as you\nopmsg: in order to create the same deniable persona on their side.\n\nopmsg: SUCCESS.\n```\n\nOfcorse, you should use a secret that nobody can guess or bruteforce, including\nupper and lower-case, digits and so on. The idea behind brainkey personas is,\nthat you share a secret with your peer once you meet, and both sides can\nthen generate the same personas independently afterwards. There's no need to verify\nfinger prints or exchange keys. The salt parameter doesn't need to be secret and may\nalso be omitted. But it is a safety measure to chose a salt in order to make attacks\nwith rainbow tables unfeasable. If you are certain that no other users\nare on your box, you may also pass the passphrase as `--brainkey1=mysupersecretnobodyknows`\non the commandline instead of typing it on `stdin`.\nBrainkeys will only be used for deniable EC personas. The Kex (aka Session) keys\nwill nevertheless be generated randomly, just as for other personas.\nBrainkey personas can then be used just as normal. Once created, you may just\nforget the brainkey, as you will never need to generate it again.\n\n\nPost-Quantum Personas\n---------------------\n\nAs of `version=4` messages, *opmsg* supports personas who resist quantum computing power.\nThese personas have type `pq1` in the `opmsg -l` listing and are basically brainkey\npersonas as above but include a symmetric salt thats used together with the ECDH Kex\nto derive the session key. The integrity of `version=4` (and above) messages is not only\nprotected by asymmetric signatures (RSA or ECC) but by also extending the AAD of AES-GCM to\nthe entire header, including exchanged keys and the Kex part. This ensures that even\nwith quantum computing power, an adversary cannot modify the message or break the session\nkeys. PQC-Personas are generated similar to `brainkey1` personas:\n\n```\n$ opmsg --name=quantum-tarantino --deniable --salt2 1234 --brainkey2 --newecp=secp521r1 --phash=sha256\n[...]\n```\n\nI.e. by using `--brainkey2` instead of `--brainkey1`.\nFor `pq1` personas, *opmsg* only accepts `aes256gcm` and `chacha20-poly1305` cipher algos,\nin order to fully protect the entire message with AAD as described above.\nThis symmetric salt solution is recommended by the BSI (Federal Office of Information\nSecurity in good old Germany) durin the transitioning phase. Note, that neither *OpenSSL*\nsupports PQC yet, nor are there any standartized algorithms, nor recommend any of the PQC\nprojects to use their code in production, so having this transitioning solution is the most\nportable way of adding PQC to *opmsg*.\n\n\nMessage Encryption\n------------------\n\nIn order to encrypt messages, you have to specify the persona ID of the recipient:\n\n```\n$ opmsg -E 12344d8921323601 --out msg1.opmsg\n...\n```\n\nIf no `--in` parameter is given, the message is read from `stdin` until `Ctrl-C`.\nThe fastest way is to use the long form of the persona ID, but its also the most\ninconvenient form. Above example uses the short ID of the target persona. It already\nrequires some searching inside the keystore for that particluar ID, but its still fast.\nThe most convenient, but slowest form allows to use names as recipient. It requires to\nsearch the entire keybase until a name-match is found. Note, that this is potentially\nambigious and you must not have more than one persona with the same name field in your\nkeystore:\n\n```\n$ opmsg --name friend@localhost -E name --in msg2 --out msg2.opmsg\n...\n```\n\n`-E name` refers to use names instead of IDs. Still, it is recommended to use the hex-id as\nrecipient, since its the more bullet-proof approach.\n\n\nKeys\n----\n\nNow for the coolest feature of _opmsg_: Perfect Forward Secrecy (PFS).\n\nWithout any need to re-code your mail clients or add bloat to the\nSMTP protocol, _opmsg_ supports PFS by means of (EC)DH Kex out of the box.\n\nFor RSA personas, DH Kex is used. For EC personas ECDH Kex is used to derive\nthe secret, hence the term (EC)DH.\n\nAs op-messages are _always_ signed by its source persona,\nwhenever you send an opmsg to some other persona, a couple of\n(EC)DH keys are generated and attached to the message. The remote\n_opmsg_ will verify its integrity (as it has this persona imported)\nand add it to this persona's keystore. So whenever this remote peer\nsends you a mail next time, it can choose one of the (EC)DH keys it has\ngot beforehand. If your peer runs out of (EC)DH keys, _opmsg_ falls\nback to native RSA or EC encryption, depending of the type of persona.\nThe peer deletes used (EC)DH pubkeys to not\nuse them twice and the local peer marks used keys with a\n`used` file within the apropriate key-directory. Once again,\n`sha256` is used by default to index and to (worldwide) uniquely\nidentify (EC)DH keys.\n\n**Attention:** If you keep encrypted op-messages in your mailbox,\ndo not throw away this persona. You wont be able to decrypt these mails\nafterwards! Throwing away a persona also means to throw away all keying\nmaterial. Thats why _opmsg_ has no switch to erase personas. You have\nto do it by hand, by rm-ing the subdirectory of your choice. Thats\neasily done, but keep in mind that any dangling op-messages in your\ninbox will become unreadable, as all keys will be lost. If you want to\nbenefit from PFS, you have to archive the **decrypted** messages and\nthrow away `used` keys. After all _opmsg_ is not a crypto container\nor a replacement for FDE (which is recommended anyway). _opmsg_ is\nabout to protect your messages in transit, not on disk.\n\nAs of `version=1.3` there is a `--burn` option that nukes used DH\nkeys from storage. Be aware: you can only decrypt the message once.\nOnce the message is successfully decrypted, the (EC)DH key that was used\nis overwritten and deleted from storage.\n\n\ncross-domain ECDH\n-----------------\n\nYou may skip this section if you are not really paranoid about potentially\nbackdoored EC curves and how to cope with it.\n\nThere is a (yet experimental) feature, which may be enabled by using protocol version 3\nand specifying more than one EC curve in the config:\n\n\n```\n...\nversion=3\n...\ncurve=brainpoolP384r1\ncurve=secp256k1\n...\n```\n\nUp to three different curves may be specified. For each curve specified, a dedicated ECDH\nhandshake is made. That is, the key used for encrypting the message is derived from more\nthan one ECDH Kex. The 'common' ECDH handshake, as seen in all other protocols like TLS etc.,\nuses one curve. _opmsg_ by default also uses one curve. But you can use more than one, and\nhere is why: There is an endless discussion about which curve can be trusted. Some prefer\nthe NIST curves, some prefer Brainpool and some prefer even other curves. As shown in\nvarious papers, it is possible by evil EC-curve designers to choose the curve domain parameters\nin a way that places backdoors into the curve. That is, by knowing certain seeding parameters,\nit is possible to create legit looking curves which fullfil all requirements, yet producing\nweak secrets, if the attacker knows the evil seeding bits. It is not just a theroretical issue\nthat evil committee members place backdoors into standards (take the dual-EC-DRBG as a warning).\n\nThe idea behind cross-domain ECDH is that, even if we assume all EC curves to contain\nbackdoored parameters, the knowledge about it is so well protected that it is not shared\nacross each other. Would the NIST share their backdoor seedings with the russians or vice versa?\nCertainly they wouldn't.\nIn other words, each backdooring party would keep their evil seeding\nfor themselfs. By using cross-domain ECDH, we exploit this fact and can negotiate a strong secret,\neven with potentially backdoored EC curves.\n\nThis is for the negotiated session keys. The persona keys (used for signing) are still generated using a single curve.\nBut you may use cross-doamin ECDH with RSA personas now, by specifying\n\n```\n...\necdh-rsa\n...\n```\n\nin the config.\n\n\nMUA integration\n---------------\n\nFirst, add to your _~/.gnupg/options_ file the following line:\n\n```\nkeyid-format long\n```\n\nNext, there are two possible ways to integrate _opmsg_ into your MUA. For cool\nMUAs like __mutt__, you may build a dedicated _.muttrc_ by adding:\n\n```\n# Add a header so to easy pick opmsg via procmail rules\nmy_hdr X-opmsg: version1\n\nset pgp_long_ids\n\n# use this listing mode if the 'name' aliases are a substring of the email address\n# to avoid huge listings\nset pgp_list_pubring_command=\"/usr/local/bin/opmsg --listpgp --short --name %r\"\n\n# otherwise, skip the --name option to list all personas\n#set pgp_list_pubring_command=\"/usr/local/bin/opmsg --listpgp --short\"\n\nset pgp_encrypt_sign_command=\"/usr/local/bin/opmsg --encrypt '%r' -i %f\"\nset pgp_encrypt_only_command=\"/usr/local/bin/opmsg --encrypt '%r' -i %f\"\nset pgp_decrypt_command=\"/usr/local/bin/opmsg --decrypt -i %f\"\nset pgp_verify_command=\"/usr/local/bin/opmsg --decrypt -i %f\"\n\n# or set to \"^opmsg: SUCCESS\\.$\" - only required for newer mutt versions\n#unset pgp_decryption_okay\n\n```\n\nand work with your mails as you would it with _PGP/GPG_ before. If you\nuse a mix of _GPG_ and _opmsg_ peers, its probably wise to create\na dedicated _.muttrc_ file for _opmsg_ and route _opmsg_ mails to\na different inbox, so you can easily work with GPG and _opmsg_ in\nparallel. Note that some mutt installs (neomutt) require the `-n` switch\nif you load your own config via `-F` in order to skip processing of system-wide\nconfig files. This would otherwise overload all of your pgp variables.\n\nBut theres also another option: Using _opmux_:\n\n```\nset pgp_long_ids\n\n# OPMUX_MUA env setting is optional and only required if you use 'pgp_decryption_okay' in newer mutts\n\nset pgp_decode_command=\"OPMUX_MUA=mutt /usr/local/bin/opmux --passphrase-fd 0 --quiet --batch --output - %f\"\nset pgp_verify_command=\"OPMUX_MUA=mutt /usr/local/bin/opmux --quiet --batch --output - --verify %s %f\"\nset pgp_decrypt_command=\"OPMUX_MUA=mutt /usr/local/bin/opmux --passphrase-fd 0 --quiet --batch --output - %f\"\n\nset pgp_encrypt_only_command=\"/usr/local/bin/opmux --batch --quiet --output - --encrypt \\\n                              --textmode --armor --always-trust -r '%r' %f\"\nset pgp_encrypt_sign_command=\"/usr/local/bin/opmux --passphrase-fd 0 --batch --quiet --textmode \\\n                  --output - --encrypt --sign %?a?-u %a? --armor --always-trust -r '%r' %f\"\n\nset pgp_list_pubring_command=\"/usr/local/bin/opmux --batch --quiet --with-colons --list-keys %r\"\n\n# Be sure to not override it later on. This regex may also be unset.\nset pgp_decryption_okay=\"^opmux: SUCCESS\\.$\"\n\n```\n\n_opmux_ is a wrapper for _opmsg_ and _gpg_, which transparently forwards encryption and decryption\nrequests to the right program, by checking message markers and persona ids.\nThis way you may use your _opmsg_ and _gpg_ setup in parallel and the correct (de)crypt program is\nautomagically invoked. When you send a Mail and an _opmsg_ persona is found for the destination,\n_opmsg_ is used for encryption, otherwise _gpg_ is used.\nThis requires your personas to be properly `--link`ed or having a valid `my_id` in your\n_opmsg_ config.\n\nFor __enigmail__ or other MUAs you would just configure the gpg-path to be `/path/to/opmux` and you\nare done (but dont forget the `keyid-format long` from the first step).\n\n_opmux_ prefers the _gpg2_ over the _gpg_ binary if both gpg versions are installed. If you\nhave both gpg versions installed in parallel but for whatever reason want to work with your (old) gpg1 keys,\nyou have to change the call order in `opmux.c` _gpg()_ function.\n\nAll this however is just for convenience. The more GUI and layering you add to your\n_opmsg_ setup, the more chance you have to use wrong destination or source personas. So\nbe sure to thoroughly test your setup. Again, make sure your personas are properly linked\nand you have a clean default persona id assigned in the config.\n\nCc and Bcc\n----------\n\nSince `version=1.65` opmsg supports Cc/Bcc from mails, e.g. you may specify more than\none `-E` persona recipient. However if you used to Cc messages to yourself for\narchiving, you must not use `--burn` because in fact you are referencing session\nkeys that were initially generated for someone else. Then at times when this peer\nsend you encrypted messages, you will miss that key.\n\nPlease note that in general using crypted mails and Cc is leaking privacy, as\nthe destination personas see whats in your keystore and which key ids you are\nreferencing. Its also asking for headache if you did not set up your keystore properly\n(linking personas and keeping the link ids up to date, removing dead personas etc.)\n\nIf you are operating, you may also consider a dedicated account (machine) with a dedicated opmsg\nsetup so that you dont accidently sign operational messages with source personas that\nlink to a publically known profile. Deniable messages wont help in that case.\n\nConfig file\n-----------\n\nYou need to setp up your local `~/.opmsg/config` to reflect\nthe source persona you are using when sending your mail via _mutt_,\nunless you specify it via `-P` on the commandline or used `--link`:\n(linking personas is recommended, see above)\n\n\n```\n# opmsg sample config\n\n# 1 or 2. Default is 2. The KDF in version=2 is hardened against evil maid attacks.\n# Only use version=2 if you know your peer uses opmsg \u003e= 1.60 that can handle version=2.\n# Your peer then automatically chooses right version. Theres no config change needed\n# for your peer.\nversion=2\n\n# Using the long format optimizes keystore loading, as an exact lookup takes place,\n# and  searching the keystore is avoided.\n# Also see 'linking personas' in README. It is recommended to use different ID\n# for each communication peer.\nmy_id = 50973f3cfc3e0f3f1a7d4047aa6fa7645510f3b4ddc486a4b72bcacdf3aad570\n\n# default\nrsa_len = 4096\n\n# default\ndh_plen = 2048\n\ncalgo = aes128ctr\n\n# the ID output format (default)\nidformat = split\n\nnew_dh_keys = 3\n\n# EC curve to be used for EC personas (prefered since its faster)\n# Default. Other choices: secp521r1 (be aware: NIST curve!), brainpoolP320t1, brainpoolP384r1,\n# brainpoolP384t1, brainpoolP512r1, brainpoolP512t1\ncurve = brainpoolP320r1\n\n# Check on decrypt whether the sender (src-id) used a kex-id that was once sent to him\n# as a dst-id.\n# This allows you detect cross-references for people using different src personas to\n# to contact a single persona of yours. This way you can detect/enforce isolation.\n# By default its disabled.\npeer_isolation=1\n\n```\n\nSupported ciphers\n-----------------\n\n```\n$ opmsg -C inv -D\n\nopmsg: version=1.64 -- (C) 2015 opmsg-team: https://github.com/stealth/opmsg\n\nopmsg: Invalid crypto algorithm. Valid crypto algorithms are:\n\nopmsg: aes128cbc (default)\nopmsg: aes128cfb\nopmsg: aes128ctr\nopmsg: aes128gcm\nopmsg: aes256cbc\nopmsg: aes256cfb\nopmsg: aes256ctr\nopmsg: aes256gcm\nopmsg: bfcbc\nopmsg: bfcfb\nopmsg: cast5cbc\nopmsg: cast5cfb\nopmsg: null\n\nopmsg: FAILED.\n```\n\nExamples\n--------\n\n```\n$ opmsg --list --short\n\nopmsg: version=1.2 -- (C) 2015 opmsg-team: https://github.com/stealth/opmsg\n\nopmsg: persona list:\nopmsg: Successfully loaded 1 personas.\nopmsg: (id)     (name)  (has-RSA-priv)  (#DHkeys)\nopmsg: 1cb7992f96663853 stealth 1       0\nopmsg: SUCCESS.\n```\nCreating a detached signature for a file:\n```\n$ echo foo\u003efoo\n$ opmsg --sign -i foo --persona 1cb7992f96663853|tee -a foo.sign\n\nopmsg: version=1.2 -- (C) 2015 opmsg-team: https://github.com/stealth/opmsg\n\nopmsg: detached file-signing by persona 1cb7992f96663853\nopmsg: SUCCESS.\n-----BEGIN OPMSG-----\nversion=1\n-----BEGIN SIGNATURE-----\nU822A12k1IZiWqRKAr6uLKT/7HGR4inKpkqzz49xLNjBf4mo91HUxcPMFGQTDB/MbE9HqtdCgHNexfIy\nGCC6Jb6egt2D70nIyhWfksW9KljdqwQzUbXp9CubxRAz5EqTS0n0ze092LuXxV4SuKV628CTBr5siIcf\nza6g3Sfh+vg=\n-----END SIGNATURE-----\nrythmz=sha256:sha256:sha256:null:DOauqyrqoH4zslO4gr3FFI7EMbcLtRzU\nsrc-id=1cb7992f966638531d33e59e83cd054295fb8016e5d9e35fb409630694571aba\ndst-id=1cb7992f966638531d33e59e83cd054295fb8016e5d9e35fb409630694571aba\nkex-id=00000000\n-----BEGIN OPMSG DATA-----\nb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c\n-----END OPMSG-----\n```\nVerifying it:\n```\n$ sha256sum foo\nb5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c  foo\n$ opmsg -V foo -i foo.sign\n\nopmsg: version=1.2 -- (C) 2015 opmsg-team: https://github.com/stealth/opmsg\n\nopmsg: verifying detached file\nopmsg: GOOD signature and hash via persona 1cb7992f96663853 1d33e59e83cd0542 95fb8016e5d9e35f b409630694571aba\nopmsg: SUCCESS.\n$ opmsg -V foo -i foo.sign --short\n\nopmsg: version=1.2 -- (C) 2015 opmsg-team: https://github.com/stealth/opmsg\n\nopmsg: verifying detached file\nopmsg: GOOD signature and hash via persona 1cb7992f96663853\nopmsg: SUCCESS.\n```\n\nMeta data\n---------\n\nIf you care about meta data collection and want to reduce your data-tracks\neven further, check out [drops](https://github.com/stealth/drops).\n_drops_ is a p2p transport network for _opmsg_. It allows you to anonymously\ndrop end2end encrypted op-messages without leaking meta-data such as mail headers.\n\n","funding_links":[],"categories":["C++","\u003ca name=\"cpp\"\u003e\u003c/a\u003eC++","Security","Hardening"],"sub_categories":["Hardening","Ghidra"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstealth%2Fopmsg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstealth%2Fopmsg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstealth%2Fopmsg/lists"}