This is a simple time-based nonce that you can used in various situations. The nonce is designed to be time-based so you can use it with a short lifetime (e.g. 5 or 10 seconds).
TimestampedNonce uses 192 bits with:
- First
64 bitsfor the expiration timestamp, milliseconds since EPOCH. - The next
128 bitsis for entropy. This is secure enough in this situation.
TimestampedNonce.toString() returns a base64-urlencoded string of the entire 192-bit octets.
SignedTimestampedNonce is a TimestampedNonce signed with HMAC-SHA256.
- The Server creates a
SignedTimestampedNonce. The Server usesSignedTimestmapedNonce#signature()to set a cookienonce_signature, then returns theSignedTimestampedNonce#signedNonce().toString()to the Client. - The Client must attach the
signedNoncein its URL Parameter or the payload. This also works for CRSF protection. - The Client must send along with the cookie
nonce_signature. - The Server verifies both the
signedNonceandnonce_signature. If both matches, proceed.
jshell> /open TimestampedNonce.java
jshell> var nonce = TimestampedNonce.expiresAt(Instant.now().plusSeconds(10));
nonce ==> AAABl6_3SdD2odb1QJjRSPHSAeRV31EV
jshell> var hmacKey = new byte[32];
hmacKey ==> byte[32] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... , 0, 0, 0, 0, 0, 0, 0, 0 }
jshell> new SecureRandom().nextBytes(hmacKey);
jshell> var signedNonce = TimestampedNonce.SignedTimestampedNonce.sign(nonce, hmacKey);
signedNonce ==> AAABl6_3SdD2odb1QJjRSPHSAeRV31EV:HMAC-SHA256:-QmQbeudWd ... UIMqZaNfZCw3J0bcUcak_r9Ak=
jshell> signedNonce.signedNonce().toString();
$37 ==> "AAABl6_3SdD2odb1QJjRSPHSAeRV31EV"
jshell> signedNonce.signature()
$38 ==> "-QmQbeudWdHkDzakn0UIMqZaNfZCw3J0bcUcak_r9Ak="
jshell> var recreate = TimestampedNonce.SignedTimestampedNonce.verify("AAABl6_3SdD2odb1QJjRSPHSAeRV31EV", "-QmQbeudWdHkDzakn0UIMqZaNfZCw3J0bcUcak_r9Ak=", hmacKey);
recreate ==> AAABl6_3SdD2odb1QJjRSPHSAeRV31EV:HMAC-SHA256:-QmQbeudWd ... UIMqZaNfZCw3J0bcUcak_r9Ak=
jshell>