Necesitamos generar URL resistentes a la manipulación indebida para acceder a un servicio, que luego se comparten con el usuario final. Las URL no contienen datos confidenciales, pero debemos asegurarnos de que no se hayan manipulado desde que se generaron. Depende del usuario final mantener estos datos confidenciales.
Parece que un MAC (como HMACSha256) sería apropiado para autenticar las URL. También me gustaría incluir un salt y una marca de tiempo para hacer que la clave MAC sea menos fácil de adivinar, y para que las URL firmadas puedan expirar de forma natural.
Estaba pensando que PBKDF2 podría ser una buena manera de generar la clave MAC, por ejemplo:
pepper = "xyzzy"
importantFullUrl = "https://....."
salt = secureRandomBits(256)
url = importantFullUrl + "&ts=987654321&salt=" + base62(salt)
signingKey = PBKDF2(pepper, salt, 10000 /*iterations*/, 256 /*bits*/)
mac = hmacSha256(url, signingKey)
signedUrl = url + "&sig=" + base62(mac)
Un enfoque alternativo que he visto omite el paso PBKDF2 y simplemente genera el MAC basado en los valores de url
y pepper
anteriores, es decir:
mac = hmacSha256(url, pepper)
¿Un enfoque ofrece significativamente más beneficios de seguridad sobre el otro? Dadas las URL, se agotará el tiempo después de un período (por ejemplo, de 24 a 48 horas), ¿importa en este caso? ¿Cómo selecciono un recuento de iteraciones adecuado para un tiempo de espera determinado?
Se describe un enfoque en esta pregunta que involucra una contraseña proporcionada por el usuario. Los usuarios de nuestro servicio se autentican mediante un mecanismo diferente y no tienen una contraseña explícitamente. Esto tampoco es para un servicio web, y todas estas URL firmadas se generarán en el lado del servidor y se volverán a comprobar en el lado del servidor.