CRC-24
CRC-24
Four base64 characters after the = in PGP armor.
- Digest
- 24-bit · 3 bytes
- HMAC
- no key mode
- Security
- NOT for security: error-detection checksum only
- Family
- 4 in CRC
Sample
- hex
- b03cb7
- base64
- sDy3
Options
Access
- Create
create("crc24") - CLI
hashes crc24 'hello world' - Tryplayground with the sample above
- Kincrc32, crc64, crc16-xmodem
Seen that short = line just above -----END PGP SIGNATURE-----? It's not part of the signature. It's a CRC-24 of the decoded bytes, in base64, there to catch a mangled copy and paste. RFC 4880 §6.1 starts it at 0xb704ce with polynomial 0x864cfb. No reflection, no final xor.
create("crc24").hash("123456789").digest; // "21cf02", the standard check value
create("crc24").hash("123456789", { encoding: "base64" }).digest; // "Ic8C", as armor prints it
crc24(bytes, "openpgp"); // the byte function, same thing
Checking a block by hand? Decode the base64 body and hash those bytes, not the text. GnuPG agrees on every input the tests throw at it. RFC 9580 says new armor shouldn't write the line anymore. gpg --enarmor 2.4 still does, so you'll keep meeting it.
It guards against typos, not attackers. Anyone can fix up a CRC after editing the body. That's the signature's job.
variant has one value so far, openpgp. Same deal as CRC-64: the next CRC-24 lands as a value, not as another algorithm.