código promocional basado en valor numérico

5

Tengo un ID de usuario de campo que tiene un valor entre 10000 y 999999. Quiero crear un código promocional que se base en este campo.

El código promocional será utilizado por los usuarios para recomendar nuevos usuarios.

Las características del código promocional:

  • no hay un campo adicional en la base de datos: a través del algoritmo, el código promocional se puede descodificar de nuevo a ID de usuario
  • difícil de adivinar el ID de usuario
  • fácil de compartir verbalmente

¿Puede sugerir algunas ideas o ejemplos sobre cómo abordar este problema?

    
pregunta GeorgiY 18.04.2018 - 12:19
fuente

3 respuestas

3
  

no hay ningún campo adicional en la base de datos: a través del algoritmo, el código promocional se puede descodificar a ID de usuario

Si bien esto generalmente se resolvería a través de una tabla adicional con referencias cruzadas, idealmente 1: n, para que una identificación de usuario pueda tener varios códigos promocionales válidos, esto parece estar explícitamente fuera de alcance. Esto también excluye códigos promocionales autoelegidos, desafortunadamente.

  

difícil de adivinar el ID de usuario

Idealmente, no debería ser posible adivinar el ID de usuario (y asegurarse de que acertó) en todo.

  

fácil de compartir verbalmente

Este podría ser el mayor problema al no usar una tabla adicional.

Propongo la siguiente solución:

Cifre sus identificadores de usuario.

Hay diferentes esquemas de encriptación que pueden producir resultados más pequeños que se pueden usar. Pero si, como lo sugiere su restricción en los cambios a la base de datos, el costo de la implementación es un factor determinante, vale la pena echarle un vistazo a RASA ya que mantiene el texto cifrado relativamente pequeño y las bibliotecas de cifrado están fácilmente disponibles.

Los bits resultantes podrían traducirse a palabras en lenguaje natural, por ejemplo, utilizando una lista de palabras para diceware .

Usando este enfoque, el texto cifrado sería fácil de comunicar (ya que es una cadena de palabras) y fácil de descifrar (traducción inversa, descifrar los bits resultantes).

Sin embargo, hay un problema: esos códigos pueden ser más largos de lo esperado (según el esquema de cifrado elegido) y pueden suponer una penalización de tiempo cuando se trata de escribirlos.

Aunque esto produce códigos más largos (en términos de tamaño de cadena), son mucho más fáciles de transmitir verbalmente, especialmente para los hablantes nativos que el resultado de base32, base64 o cualquiera de los enfoques habituales para la codificación de transporte.

Por lo tanto, a pesar de que una tabla 1: n sería ideal, usar el esquema de encriptado de ajuste y terminar con un código de 3 palabras podría ser la mejor opción, y definitivamente más fácil de compartir verbalmente que los sospechosos habituales para la codificación de datos. .

    
respondido por el Tobi Nary 18.04.2018 - 13:10
fuente
2

Recomendaría el siguiente enfoque:

  • Cifre el ID de usuario con un algoritmo que produzca resultados pequeños, por ejemplo, Tiene un tamaño de bloque pequeño. Un elemento alternativo sería Cifrado Hasty Pudding con un tamaño de bloque de 32 bits.
  • Codifique la salida con base32 . Luego obtienes un código de promoción de siete letras.
  • Para obtener un ID de usuario de un código de promoción, simplemente invierta el proceso: descifre y descifre.

Debo admitir que no estoy seguro de cómo el tamaño del bloque pequeño afecta la seguridad del cifrado en su caso de uso. Así que antes de declarar esta prueba de agua, es posible que desee examinar eso.

Tenga en cuenta que esto sería muy fácil de hacer de forma segura con solo usar una tabla de traducción, relacionando códigos de promoción aleatorios con los usuarios. Sin embargo, eso violaría su requisito de que no se necesiten modificaciones a la base de datos.

    
respondido por el Anders 18.04.2018 - 13:20
fuente
1

Mantener el ID de usuario oculto es fácil. La dificultad es la prevención de colisiones: la mayoría de las funciones de hash que son tan cortas que se pueden comunicar fácilmente, o que están truncadas en esa longitud, colisionarán al azar.

Lo mismo se aplica a las funciones de cifrado: dado que el cifrado fuerte produce un texto cifrado de tipo aleatorio, producirá colisiones debido a la paradoja del cumpleaños. Entonces, lo que necesita es una transformación uno a uno.

Un enfoque es usar un PRNG con un período determinista y suficiente y solo su número anterior como estado, como LFSR , con UserID como el número de rondas. El inconveniente es que puede ser lento a menos que esté escrito en un lenguaje compilado rápido.

Una forma más sencilla es cifrar el valor con un cifrado de bloque muy corto. Skip32 se puede implementar casi sin esfuerzo. Hasty Pudding es un ajuste aún más cercano, ya que se puede configurar en un bloque de 20 bits.

Para la traducción verbal, 20-21 bits se traduce a 7 números o cinco alfanuméricos de 5 bits con 2-5 bits de repuesto. Los bits de repuesto son necesarios como un dígito de verificación contra errores tipográficos. Puede usar solo esos 2-5 bits si su base de usuarios es pequeña ahora y agregar un dígito de control más a medida que su base de usuarios se acerque a un millón.

Personalmente, prefiero un alfanumérico corto a una frase de contraseña: este último crea la tentación de confiar en la memoria, y la memoria humana a menudo sustituye las palabras por los sinónimos. Los códigos y los números son más fáciles de escribir y la gente generalmente puede hacerlo. OTOH, una frase de contraseña no requiere dígitos de verificación, ya que su diccionario limitado es un cheque en sí mismo. Se trata de su caso de uso y su preferencia.

Todos estos enfoques son inseguros; LFSR ni siquiera es un cifrado, los otros dos son bastante débiles. Pero su seguridad está limitada por la corta duración del código de invitación y la necesidad de evitar la colisión garantizada.

    
respondido por el Therac 18.04.2018 - 20:56
fuente

Lea otras preguntas en las etiquetas