Rspamd

Encrypting data in Rspamd using rspamd_cryptobox_secretbox

local rspamd_text = require "rspamd_text"
local rspamd_util = require "rspamd_util"
local secretbox = require "rspamd_cryptobox_secretbox"

local sbox_key = rspamd_text.randombytes(24)
local nonce = rspamd_text.randombytes(24)

local sbox = secretbox.create(sbox_key)

local encrypted = sbox:encrypt('secret data', nonce)

key_b64 = rspamd_util.encode_base64(sbox_key)
nonce_b64 = rspamd_util.encode_base64(nonce)
encrypted_data_b64 = rspamd_util.encode_base64(encrypted)

Adding to the mail header:

local function splitByChunk(text, chunkSize, nlines)
    local s = {}
    for i=1, #text, chunkSize do
        s[#s+1] = text:sub(i,i+chunkSize - 1)
    end

    local fchars = "\r\n"
    if nlines == 'cr' then
        fchars = "\r"
    elseif nlines == 'lf' then
        fchars = "\n"
    end

    return table.concat(s, fchars)
end

-- encoded = version:key:nonce:encrypted_data
local encoded = '0:' .. tostring(key_b64) .. ':' .. tostring(nonce_b64) .. ':' .. tostring(encrypted_data_b64)

local encoded_version = splitByChunk(encoded, 120, task:get_newlines_type())

local header_report = task:get_header('X-Antispam-Report')
if not header_report then
    task:set_milter_reply({
        add_headers = {['X-Antispam-Report'] = encoded_version}
    })
elseif header_report and header_report ~= encoded_version then
    task:set_milter_reply({
        remove_headers = {['X-Antispam-Report'] = 1},
        add_headers = {['X-Antispam-Report'] = encoded_version}
    })
end

Golang

Decrypting data in Golang using golang.org/x/crypto/nacl/secretbox and golang.org/x/crypto/blake2b

func decryptReport(key, nonce, data string) ([]byte, error) {
    sboxKey, err := base64.StdEncoding.DecodeString(key)
    if err != nil {
        return nil, err
    }

    sboxHash := blake2b.Sum256(sboxKey)

    noncetxt, err := base64.StdEncoding.DecodeString(nonce)
    if err != nil {
        return nil, err
    }

    encrypted, err := base64.StdEncoding.DecodeString(data)
    if err != nil {
        return nil, err
    }

    var decryptNonce [24]byte
    copy(decryptNonce[:], noncetxt)

    decrypted, ok := secretbox.Open(nil, encrypted, &decryptNonce, &sboxHash)
    if !ok {
        return nil, errors.New("unable to decrypt")
    }

    return decrypted, nil
}