> If your app has a server component that acts on this state, be super careful about acting on it and treat it as you would any other input under user control.
I would recommend signing it if it's generated by the server component, and checking the signature when the server component is provided this signed state.
For example to do this in Node is quite straightforward.
Key generation:
const crypto = require('crypto');
crypto.generateKeyPair('ed25519', (e, pubkey, privkey) => {
// save pubkey and privkey somewhere
// ...
}
Signing: const data = Buffer.from(JSON.stringify(state));
const signature = crypto.sign(null, data, privkey);
const signeddata = `${data.toString('base64')}.${signature.toString('base64')}`.replace(/=/g,'');
Verification: const parts = signeddata.split('.');
const data = Buffer.from(parts[0], 'base64');
const signature = Buffer.from(parts[1], 'base64');
if (crypto.verify(null, data, pubkey, signature)) {
// signature not verified, throw or return
// ...
}
const state = JSON.parse(data);
As the above uses Ed25519 the signatures are quite small too. It needs a bit more error checking, and might need extras like expiry time and such, but should be roughly sufficient.