Estoy trabajando en la autenticación de mi JSON-RPC API
y mi estrategia de trabajo actual es usar solicitudes firmadas enviadas a través de POST
sobre SSL
.
Me pregunto si alguien puede ver alguna vulnerabilidad que no haya tenido en cuenta con el siguiente método de firma.
Todas las comunicaciones entre el cliente y el servidor se realizan a través de las solicitudes POST
enviadas a través de SSL
. Las solicitudes inseguras de http
son denegadas directamente por el servidor de la API.
Dependencias
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';
Solicitar objeto
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');
Empaque de carga útil (Enviado como texto claro a través de POST a través de TLS)
var payload = {
request: request,
publicKey : publicKey,
signature : signature
}
Solicitud POST
MyAPI.post('/', payload, function(error, response, body){
console.log(result);
});
Carga útil resultante
{
"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",
}
Server-Side
Y luego, en el lado del servidor, ocurre lo siguiente para autenticar la solicitud:
- PUBLIC_KEY se utiliza para buscar el SECRET_KEY en la base de datos.
- SECRET_KEY se usa para crear un HMAC del objeto
request
a partir de la carga útil. - El hash enviado en la carga útil se compara con el hash creado en el servidor. Si coinciden, el PUBLIC_KEY se autentica.
- El
timestamp
se evalúa y la autenticación se rechaza si la solicitud es demasiado antigua; de lo contrario, la marca de tiempo se autentica.
Según tengo entendido, este es un método seguro para firmar y autenticar solicitudes enviadas a través de SSL
. ¿Esto es correcto?
Gracias de antemano por cualquier ayuda.