Penso a una sheme di autenticazione di un'API REST in un'impostazione in cui l'unica cosa che il server memorizza su un client è la loro chiave pubblica (lo schema di crittografia asimmetrico non dovrebbe avere importanza). Quindi ho ideato uno schema in cui le richieste autenticate avrebbero un aspetto simile a questo:
{
body: {
<actual request body>
},
auth: {
pubKey: <user's public key and identifier as well>
nonce: <UUID generated by the client>
signature: <signature of [body, nonce]>
}
}
La firma è lì ovviamente per garantire che la richiesta è stata inviata dall'utente e non è stata manomessa. Il nonce è lì per evitare attacchi di replay. Ovviamente, il nonce può essere usato solo una volta. Il nonce deve essere un UUID, quindi il server può scartare automaticamente nonces al di fuori di un certo intervallo di tempo (diciamo + - 60 secondi), ma devo ancora occuparmi di nonces all'interno di quella finestra di 120 secondi.
E qui arriva la mia domanda principale: come archiviare in modo efficiente i nonces utilizzati in un determinato intervallo di tempo?
Mi è venuto in mente di utilizzare un filtro di fioritura per questo, ma ovviamente, può essere inquinato dopo un certo periodo di tempo, quindi è necessario ripristinarlo una volta ogni tanto. E poco dopo il ripristino sarebbe vulnerabile. Quindi la mia idea è di averne due e ruotarli - ogni nonce passerebbe attraverso entrambi, ma vorrei chiedere la presenza (non) solo di quello vecchio. L'approccio è corretto? Esiste uno "standard di settore" per la prevenzione della ripetizione di nonce adatto al mio caso d'uso?
Un'altra domanda: dove inseriresti la parte "auth" della richiesta? Esiste un modo standard per archiviare la firma e il nonce nell'intestazione o anche un modo standard per eseguire l'autenticazione della chiave asimmetrica nelle API REST che suggeriresti?