No description
  • Rust 87.5%
  • Roff 10.4%
  • HTML 2.1%
Find a file
2026-05-08 16:45:18 +02:00
LICENSES Comply with version 3.3 of the REUSE Specification 2026-05-07 15:30:44 +02:00
opensmtpd-filter-sake Remove the broken OpenSMTPD integration test script 2026-05-07 15:33:27 +02:00
sake-app Add the sake web app 2026-05-08 16:45:18 +02:00
.gitignore Comply with version 3.3 of the REUSE Specification 2026-05-07 15:30:44 +02:00
Cargo.lock Add the sake web app 2026-05-08 16:45:18 +02:00
Cargo.toml Add the sake web app 2026-05-08 16:45:18 +02:00
deny.toml Add the sake web app 2026-05-08 16:45:18 +02:00
README.md Convert the repository into a workspace for all the sake-related projects 2026-05-07 15:09:10 +02:00
REUSE.toml Add the sake web app 2026-05-08 16:45:18 +02:00
rustfmt.toml Comply with version 3.3 of the REUSE Specification 2026-05-07 15:30:44 +02:00

Sub-Address KEy (SAKE) filter

Sub-address key filter for OpenSMTPD.

What is the purpose of this project?

When giving your email address to someone, for example when registering an account on a website, a good practice is to give an unique address for each recipient. This way, if you start receiving spam on this unique address, you know which service has leaked your email address. One common way to do so is to use the sub-address delimiter (by default, the character +) in order to add a part with the service's name.

The problem is, people know that whatever is after the + can be discarded, and therefore some services drops it. This can also happen after a leak if the spammer doesn't want you to know which website has been breached. Furthermore, a spammer could also add a custom part after the + in order to cover its tracks.

Changing the default sub-address delimiter is a good idea, but isn't completely secure: in most cases, anyone will see the pattern you are using and will be able to deduce your email address for other services. For instance, if someone knows that you registered on www.acme-corp.example.com using the address darra.acme-corp@mail.example.org and on www.super-social.example.com using the address darra.super-social@mail.example.org, this person will deduce that your address on any service named x will be darra.x@mail.example.org.

This filter adds a way to configure some addresses (or aliases) in a way that the part after the sub-address delimiter includes a verification code that cannot be guessed. Following the previous example using the dot instead of the plus character as a sub-address delimiter, the addresses could be darra.acme-corp.nbvtenby@mail.example.org and darra.super-social.heywkmrx@mail.example.org. As you can see, a 5 bytes code in base32 has been added after the second delimiter.

This verification code is derived from both the address itself and a private key that only you and your email server know. Any email sent to this address without a valid authentication code will be rejected with 550 No such recipient here. Therefore, one must know the private key in order to generate new valid addresses, which means only you can do so.

Project architecture

This project uses two components:

  • a compatible MTA (Mail Transfer Agent)
  • a client application

Those two components are completely independent and do not communicate between each others. However they must be configured with the same properties (email address and private key).

Mail Transfer Agent

An MTA (Mail Transfer Agent) is the part of an email server that implements the SMTP protocol. Popular MTAs includes Postfix, Exim, OpenSMTPD and many more.

In the case of SAKE, a compatible MTA has the responsibility to either accept or reject emails addressed to email addresses that uses SAKE. This is done by checking whether or not the verification code contained in the email address is valid or not.

Currently, no MTA is natively compatible with SAKE. It is however possible to add a plugin to an existing MTA so it become compatible with SAKE. The opensmtpd-filter-sake directory contains such plugin for the OpenSMTPD email server.

In addition to being compatible, the MTA must be configured in such a way that the MTA is able to know which email address should use SAKE and which address should not, as well as which key to use.

Client application

The only purpose of the client application is to enable the user to generate email addresses that includes a validation code. Because of this, they can take many forms (Web, mobile, CLI, TUI, GUI,…). In order to work, the client application requires to know which email address to use as well as the private key associated with this address. Once it is configured, it is fully autonomous and therefore does not need any network connection.

A ready to use client application is the sake.email web application. Although it is available on the web, it only stores data in the browser's local storage. Once loaded is the browser it can therefore be used even if the network connection is lost. Be aware that there is absolutely no server storage, cleaning your local storage will wipe out all configured accounts.

Code generation protocol

Let start with some definition. For this protocol, an email address is composed of a local part, a sub-address delimiter, a sub-address, another sub-address delimiter, the validation code, the at sign and the domain name. For instance, for the address darra.service.gizti5lj@mail.example.org:

  • local part: darra
  • sub-address delimiter: .
  • sub-address: service
  • validation code: gizti5lj
  • domain name: mail.example.org

The code generation protocol is based on the HMAC-SHA-256 function. The hasher is configured with the private key, then the following data is hashed, in this order: the local part, the sub-address delimiter and the sub-address.

This hash is then reduced to 5 bytes using the following dynamic offset truncation method. From the last byte of the hash, we take the last 4 bits, which gives an offset between 0 and 15. We then take the 5 bytes of the hash located at this offset.

The code is then generated by encoding those 5 bytes using base32 (RFC 4648) without padding.

Frequently Asked Questions

Do I need to have several mailboxes?

No.

The local part can either be a real mailbox or an alias. It is up to you to decide how to setup you mail server.

Does it works with Postfix / Exim / whatever?

Not yet.

Does it supports IDN?

Yes, internationalized domain names (IDN) are supported. You can specify domain names either using valid UTF-8 or Punycode (RFC 3492).

How do I generate a private key?

Privates keys must have a length of either 128 bits (16 bytes) or 256 bits (32 bytes). Unless you have some very specific needs, you should choose a 128 bits key. You can generate a base64-formated one using OpenSSL:

openssl rand -base64 16

What about key rotation?

Rotating the key would mean that all previously generated addresses for this local part would suddenly be invalid. Therefore, the key associated with a local part must not change.

That said, you can add a new local part that uses a new key and stop using the previous one. To this end, it is recommended to use discardable names. Local parts composed of one to three characters without special meaning are good candidates to this.

Is the code cryptographically secure?

No, it is not.

Efforts have been made so it is almost impossible to use one or several known valid addresses to create new addresses or recover the key. However, it may not be considered cryptographically secure because of code's short length (5 bytes).

Can you detail the efforts made to get a mostly secure code?

At the time of writing, the HMAC-SHA-256 function has no known vulnerability.

The dynamic offset truncation is a simplified version of the one defined in section 5.3 of RFC 4226 (HOTP: An HMAC-Based One-Time Password Algorithm). However, reducing the 32 bytes output into 5 bytes can never be considered completely secure.

Therefore, although it cannot be considered cryptographically secure, efforts have been made to generate a code that is sufficiently resistant to most attackers.

If your threat-model includes attackers that are backed by a government or a powerful criminal organization, you should seek for professional help instead of trusting random projects on the internet.