Encrypt in Rspamd and Decrypt in Golang
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
}