in Uncategorized

Envelope for Signatures

In Magic Signatures for Salmon, John Panzer describes a way to pass signed XML data without involving XML canonicalization (c14n). Anyone who has dealt with WS-Security specs knows that canonicalization can be fragile (back in my days at BEA, getting signatures to work on the WebLogic stack turned out to be hard due to bugs in the c14n implementation) and slow. John Panzer’s approach is quite simple, but it requires introducing an XML based envelope format.

In John’s approach, to send signed XML, the sender does the following.

  • Serialize the XML using into UTF-8 encoded text.
  • Generate a signature of the BASE64 encoded data.
  • Use an XML envelope to send the BASE64 encoded data and the signature.

Before decoding BASE64 data, the receiver first verifies the signature of the BASE64 encoded data. If the signature matches, the receiver BASE64 decodes the data, and then parses the decoded text into XML.The most elegant part of this process is that canonicalization is not needed.

The envelope in his example looks like the following:

 
<me:env xmlns:me='http://salmon-protocol.org/ns/magic-env'>
  <me:data type='application/atom+xml' encoding='base64'>
PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4KPGVudHJ5IHhtbG5
zPSdodHRwOi8vd3d3LnczLm9yZy8yMDA1L0F0b20nPgogIDxpZD50YWc6ZXhhbXBsZ
S5jb20sMjAwOTpjbXQtMC40NDc3NTcxODwvaWQ-ICAKICA8YXV0aG9yPjxuYW1lPnRlc3RAZXhhbXBsZS5jb208L25hbWU-PHVyaT5hY2N0OmpwYW56ZXJAZ29vZ2xlLmNvbTwvdXJpPjwvYXV0aG9yPgogIDx0
aHI6aW4tcmVwbHktdG8geG1sbnM6dGhyPSdodHRwOi8vcHVybC5vcmcvc3luZGljYX
Rpb24vdGhyZWFkLzEuMCcKICAgICAgcmVmPSd0YWc6YmxvZ2dlci5jb20sMTk5OTp
ibG9nLTg5MzU5MTM3NDMxMzMxMjczNy5wb3N0LTM4NjE2NjMyNTg1Mzg4NTc5
NTQnPnRhZzpibG9nZ2VyLmNvbSwxOTk5OmJsb2ctODkzNTkxMzc0MzEzMzEyNzM
3LnBvc3QtMzg2MTY2MzI1ODUzODg1Nzk1NAogIDwvdGhyOmluLXJlcGx5LXRvPgog
IDxjb250ZW50PlNhbG1vbiBzd2ltIHVwc3RyZWFtITwvY29udGVudD4KICA8dGl0bGU-U2FsbW9uIHN3aW0gdXBzdHJlYW0hPC90aXRsZT4KICA8dXBkYXRlZD4yMDA5LTEyLT
E4VDIwOjA0OjAzWjwvdXBkYXRlZD4KPC9lbnRyeT4KICAgIA==</me:data>
  <me:alg>RSA-SHA1</me:alg>
  <me:sig>EvGSD2vi8qYcveHnb-rrlok07qnCXjn8YSeCDDXlbhILSabgvNsPpbe
76up8w63i2fWHvLKJzeGLKfyHg8ZomQ==>/me:sig>
</me:env>

In this XML envelope, the me:data element contains BASE64 encoded data. The type attribute tells that the data is an Atom document. The me:sig element contains the signature.

But does sending a signature require an envelope? Here is an alternative that does not use an envelope.

 
Content-Encoding: base64
Content-Type: application/atom+xml;chatset=UTF-8
Authorization: salmon EvGSD2vi8qYcveHnb-rrlok07qnCXjn8YSeCDDXlbhILSabgvNsPpbe76up8w63i2fWHvLKJzeGLKfyHg8ZomQ==

D94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4KPGVudHJ5IHhtbG5
zPSdodHRwOi8vd3d3LnczLm9yZy8yMDA1L0F0b20nPgogIDxpZD50YWc6ZXhhbXBsZ
S5jb20sMjAwOTpjbXQtMC40NDc3NTcxODwvaWQ-ICAKICA8YXV0aG9yPjxuYW1lPnRlc3RAZXhhbXBsZS5jb208L25hbWU-PHVyaT5hY2N0OmpwYW56ZXJAZ29vZ2xlLmNvbTwvdXJpPjwvYXV0aG9yPgogIDx0
aHI6aW4tcmVwbHktdG8geG1sbnM6dGhyPSdodHRwOi8vcHVybC5vcmcvc3luZGljYX
Rpb24vdGhyZWFkLzEuMCcKICAgICAgcmVmPSd0YWc6YmxvZ2dlci5jb20sMTk5OTp
ibG9nLTg5MzU5MTM3NDMxMzMxMjczNy5wb3N0LTM4NjE2NjMyNTg1Mzg4NTc5
NTQnPnRhZzpibG9nZ2VyLmNvbSwxOTk5OmJsb2ctODkzNTkxMzc0MzEzMzEyNzM
3LnBvc3QtMzg2MTY2MzI1ODUzODg1Nzk1NAogIDwvdGhyOmluLXJlcGx5LXRvPgog
IDxjb250ZW50PlNhbG1vbiBzd2ltIHVwc3RyZWFtITwvY29udGVudD4KICA8dGl0bGU-U2FsbW9uIHN3aW0gdXBzdHJlYW0hPC90aXRsZT4KICA8dXBkYXRlZD4yMDA5LTEyLT
E4VDIwOjA0OjAzWjwvdXBkYXRlZD4KPC9lbnRyeT4KICAgIA==

In this case, the Authorization header contains the signature, and the body of HTTP message contains base64 encoded bytes. I extended Content-Encoding to specify base64. I left out details like the signature method name, and the Authorization header can be extended to include such data, or such details can be specified as part of the authorization scheme (the way basic auth, digest auth, or OAuth do).

The magic envelope is HTTP (thanks to MIME).

  • Related Content by Tag