Sto lavorando all'autenticazione per il mio JSON-RPC API
e la mia strategia di lavoro corrente utilizza le richieste firmate inviate tramite POST
a SSL
.
Mi chiedo se qualcuno possa vedere eventuali vulnerabilità che non ho preso in considerazione con il seguente metodo di firma.
Tutte le comunicazioni tra il client e il server avvengono tramite% richieste diPOST
inviate su SSL
. Le richieste http
non sicure sono negate a titolo definitivo dal server API.
Dipendenze
var uuid = require('node-uuid');
var crypto = require('crypto');
var moment = require('moment');
var MyAPI = require('request-json').newClient('https://api.myappdomain.com');
Vars
var apiVersion = '1.0';
var publicKey = 'MY_PUBLIC_KEY_UUID';
var secretKey = 'MY_SECRET_KEY_UUID';
Richiedi oggetto
var request = {
requestID : uuid.v4(),
apiVersion : apiVersion,
nonce : uuid.v4(),
timestamp : moment.utc( new Date() ),
params : params
}
Firma
var signature = crypto.createHmac('sha512',secretKey).update(JSON.stringify(request)).digest('hex');
Pacchetto di payload (inviato come testo in chiaro tramite POST su TLS)
var payload = {
request: request,
publicKey : publicKey,
signature : signature
}
Richiesta POST
MyAPI.post('/', payload, function(error, response, body){
console.log(result);
});
Payload risultante
{
"request" : {
"requestID" : "687de6b4-bb02-4d2c-8d3a-adeacd2d183e",
"apiVersion" : "1.0",
"nonce" : "eb7e4171-9e23-408a-aa2b-cd437a78af22",
"timestamp" : "2014-05-23T01:36:52.225Z",
"params" : {
"class" : "User"
"method" : "getProfile",
"data" : {
"id" : "SOME_USER_ID"
}
}
},
"publicKey" : "PUBLIC_KEY",
"signature" : "7e0a06b560220c24f8eefda1fda792e428abb0057998d5925cf77563a20ec7b645dacdf96da3fc57e1918950719a7da70a042b44eb27eabc889adef95ea994d1",
}
sul lato server
E quindi sul lato server si verifica quanto segue per autenticare la richiesta:
- PUBLIC_KEY viene utilizzato per cercare SECRET_KEY nel DB.
- SECRET_KEY viene utilizzato per creare un HMAC dell'oggetto
request
dal payload. - L'hash inviato nel payload viene confrontato con l'hash creato sul server. Se corrispondono, PUBLIC_KEY è autenticato.
- Il
timestamp
viene valutato e l'autenticazione viene rifiutata se la richiesta è troppo vecchia, altrimenti il timestamp viene autenticato.
Per quanto ho capito, questo è un metodo sicuro per la firma e le richieste di autenticazione inviate su SSL
. È corretto?
Grazie in anticipo per qualsiasi aiuto.