An empty form field looks unimportant. In ordinary application logic, treating an empty value like a missing value is often reasonable. In signature verification, that assumption can reject a legitimate message—or, in a different protocol, verify a representation the sender never signed.
The important lesson is simple: canonicalization is not generic data cleanup. It is part of the cryptographic protocol.
The tidy abstraction that hid a real difference
Consider an integration with two flows:
The application builds an outbound form and signs it.
A provider later sends an inbound form notification that the application verifies.
Both flows need URL encoding, ordered key=value pairs, a digest, and a comparison. A shared helper therefore seems sensible.
But suppose the protocol defines different empty-field rules. The outbound form omits empty values. The inbound notification includes every posted field, even an empty one represented as description= .…