Verification
Signing key.
Every email we send, and any receipt you ask for, is signed by this server. Here is the key to check them against, and how to do it.
Signing is not switched on.
This server has no signing key installed, so nothing it sends carries a signature. If you are holding an email from us that has a signature block on it, it did not come from this server as it stands today.
What is signed
Two things, and what each one proves.
Emails
Every message, including the internal alerts nobody outside sees. The signature covers the recipient, the subject, the message kind, the time it was signed, and a SHA-256 of the plain-text body as it stood before the signature block was appended.
The HTML version is not signed. Mail clients rewrite HTML in transit as a matter of course, so a signature over it would fail for reasons that have nothing to do with authenticity - and a check that cries wolf is worse than no check.
Page receipts
Ask for one with the link at the foot of any page. It covers the time, your IP address, your browser’s user agent, whether the request was from a logged-in admin, the page address, and a SHA-256 of the HTML this server returns for it.
Worth knowing: the hash is of what the server serves when the receipt is taken. Most pages here are cached and identical between visits, but a page whose content changes - the reviews list, for instance - can hash differently from what you saw a minute earlier.
What a signature does and does not prove
It proves this server produced that exact content, and that it has not been altered since. That is genuinely useful: a forwarded email claiming to be from us either verifies against this key or it does not.
It does not prove when, in any sense that would satisfy somebody adversarial. The timestamp inside the signature is this server’s own clock, and this server holds the key - so it could in principle sign something with any date on it. Treat the time as a good-faith record, not as proof against us. Anything needing more than that wants a third-party timestamp authority, which we do not currently use.
How to check one
Three ways, all offline.
Save the key above as server_public.pem. Every signature block tells you the exact bytes that were signed, one key=value per line, joined with newlines and no trailing newline. Reconstruct that, and check it.
The signed payload for an email
type=email to=<lowercased recipient> subject=<subject line> kind=<the message kind> contentSha256=<from the block> signedAt=<from the block> keyId=<from the block>
A page receipt is the same idea with type=page-visit and its own fields - and it hands you the payload verbatim in signedPayload, so there is nothing to reconstruct.
openssl
printf '%s' "$PAYLOAD" > payload.txt echo "$SIG_BASE64" | base64 -d > sig.bin openssl dgst -sha256 -verify server_public.pem -signature sig.bin payload.txt
Node
crypto.verify("sha256", Buffer.from(payload, "utf8"),
fs.readFileSync("server_public.pem"),
Buffer.from(sigBase64, "base64"));Java
Signature s = Signature.getInstance("SHA256withRSA");
s.initVerify(publicKey);
s.update(payload.getBytes(StandardCharsets.UTF_8));
boolean ok = s.verify(Base64.getDecoder().decode(sigBase64));Use Signature, not Cipher. Verifying with Cipher.getInstance("RSA/ECB/PKCS1Padding") means doing raw RSA and inspecting the padding by hand, which is a well-known way to accept forged signatures.
There is also a script in the repository - node scripts/verify-signature.mjs - which takes an email or a receipt and does all of the above for you.
Questions about a signature you are holding: checkedweekly@appliedspeedtechnologies.com. The key itself is served from https://appliedspeedtechnologies.com/business/key over TLS, so a man in the middle cannot hand you a different one without also breaking the certificate.
