As serializing and deserializing JSON is not deterministic, but may depend on the order in which keys are added or even the system's collation method, signing JSON cryptographically is fraught with issues. We circumvent them by wrapping any JSON to be signed in another JSON object:
version
contains the version of the wrapper JSON, currently always 1
.serialized
contains the serialized version of the data, currently this
will be the base64 encoded, serialized JSON payload.signature
contains the base64 encoded signature of the serialized
field
value prior to its base64 encoding.payload
[optional] contains the deserialized JSON object corresponding
to the serialized
payload.For signing and verification, we'll use polkadot's ed25519
or sr25519 keys
directly.
Given some structured data:
version
field.serialized
field.signature
field.payload
field.version
, serialized
and signature
field.version
field's value is 1
.serialized
and signature
fields.signature
is valid for the decoded serialized
field.serialized
field.payload
field, and return the
modified object.There are alternative schemes available for signing JSON objects, but they have specific issues we'd like to avoid.
ed25519
or sr25519 keys used in polkadot apps, and
appears to be fraught with security issues.
Either makes its use hard to justify.ed25519
keys and seems to have
a reasonably robuts JavaScript implementation, it requires its secret keys to
be 512 bits long, while polkadot provides 256 bit secret keys. The implication
is that we would have to manage 512 bit keys and their corresponding public
keys as linked to polkadot's keys, which is cumbersome at the very least.