Programación en Pawn - SAMP

[Plugin] Bcrypt - Deja de arriesgar tus datos.

¿Encontraste un Plugin que te asombró? ¿Qué opinas de mostrárnoslo? ¡Súbelo y compártelo con los demás! También, encuentra gran cantidad de Includes.
Reglas del Foro

  • Si publicas un Plugin de tu autoría, deberás publicar el código fuente del mismo. No olvides utilizar el BBCode [Pawn]Código aquí[/Pawn].
  • Si no eres el autor del plugin/include o has utilizado códigos de otros autores, recuerda colocar los créditos correspondientes. (El plagio es motivo de sanción).

Moderador: Ayudantes

Hola.

No tenía pensado hacer ningún aporte hoy, pero aquí estoy al final. La verdad es que no entiendo por qué, una buena parte de los servidores no almacena de forma segura los datos de los usuarios. Y lo peor no es solo eso, sino que muchas veces, para las contraseñas usa algoritmos de hashing bastante débiles o con colisiones. Véase MD5, o incluso SHA1.

Podríais argumentar que SHA256 es seguro, pero si decís eso, vuestro argumento es inválido.

Hoy en día, los algoritmos para hashear contraseñas considerados más seguros son:
  • Argon2
  • PBKDF2
  • scrypt
  • Bcrypt
Desafortunadamente, en SAMP no tenemos soporte para los otros. No pasa tampoco nada, ya que bcrypt es un algoritmo que va a seguir siendo de los más seguros a medio-largo plazo.

bcrypt para SAMP

El plugin que hoy os traigo es de lassir, y se llama bcrypt-samp, el cual es una implementación de bcrypt para samp.

Es asíncrona, ya que bcrypt consume bastante más potencia de computado que otros algoritmos más simples (e inseguros).


Instalación

Para instalarlo: Si hemos usado el primer método, tan solo incluímos ahora
 Codigo Pawno:
1

#include <bcrypt>
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
Si usamos el segundo, tendremos que colocar el plugin en su carpeta, y el include también en la suya.

Sus funciones

Funciones:
 Codigo Pawno:
1
2
3
4
5
6
7
8

bcrypt_hash(key[], cost = 12, callback_name[], callback_format[] = "", {Float, _}:...); // Manda un texto a encriptar.
bcrypt_get_hash(dest[]); // Función que será llamada en el callback para obtener hash
bcrypt_check(key[], hash[], callback_name[], callback_format[] = "", {Float, _}:...); // Manda una comprobación entre un hash y un texto
bool:bcrypt_is_equal(); // Función que se llama en el callback para comprobar si coincide el hash mandado y el texto
bool:bcrypt_needs_rehash(hash[], cost); // Para comprobar si necesita volver a ser hasheado la contraseña hasheada.
bcrypt_find_cost(time_target = 250); // Encontrar el costo estimado basado en tiempo en milisegundos.
bcrypt_debug(BCRYPT_DEBUG_LEVEL:level = BCRYPT_LOG_ERROR); // Nivel de debug.
bcrypt_set_thread_limit(value); // Establece un máximo de threads concurrentes para ser usados por el plugin.
  Cantidad de llaves: Abiertas(2)-Cerradas(2) | Lineas Totales: 8
En este tutorial solamente vamos a trabajar con las cuatro primeras funciones.

¿Cómo se usa?

Hashear una contraseña
Para hashear la contraseña de un usuario:
 Codigo Pawno:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <bcrypt>
#define BCRYPT_COST 12 // Este coste está bien. Ni consume mucho, ni es inseguro.

// En alguna parte de tu gamemode, como por ejemplo cuando el usuario en el registro introduce su contraseña
bcrypt_hash("micontraseña", BCRYPT_COST, "OnPasswordHashed", "d", playerid);

forward OnPasswordHashed(playerid);
public OnPasswordHashed(playerid) // El callback será llamado cuando termine el hasheo el plugin
{
	new hash[BCRYPT_HASH_LENGTH];
	bcrypt_get_hash(hash); // Almacena el hash en la variable hash, por lo que podemos usarla para guardar en la base de datos.
	
	printf("El hash para el jugador %d: %s", playerid, hash); // Esto se puede quitar, es solo par que veáis como funciona.
	return 1;
}
  Cantidad de llaves: Abiertas(1)-Cerradas(1) | Lineas Totales: 15
Comprobar si la contraseña es correcta
El código de bcrypt_check se podría poner por ejemplo, en los diálogos de login, cuando el usuario introduce su contraseña.
 Codigo Pawno:
1
2
3
4
5
6
7
8
9
10

bcrypt_check("micontraseña", "$2y$12$a250ZgU7rRlP8GC41eJLGeCDOTrr3yNTrEo3mzH8eNXqpCN9fhgOu",  "OnPasswordChecked", "d", playerid); // Donde va $2 y lo que continúa, sería el hash.

forward OnPasswordChecked(playerid);
public OnPasswordChecked(playerid)
{
	new bool:match = bcrypt_is_equal(); // Si match es verdadero, la contraseña será correcta. Si no, no lo será.

	printf("La contraseña introducida por el usuario %d: %s", playerid, (match) ? ("coincide") : ("no coincide")); // Esto se puede quitar, es solo par que veáis como funciona.
	return 1;
}
  Cantidad de llaves: Abiertas(1)-Cerradas(1) | Lineas Totales: 10

Créditos

A Lassir, por crear este maravilloso y útil plugin.
¿A mí? Supongo, por hacer este post.

Si tenéis dudas, podéis dejarlas por aquí. No lo veo un plugin complicado ni mucho menos, y creo que con los dos ejemplos que he dejado queda bastante claro su uso.

Un saludo -hi
Excelente y grandioso aporte eh, aunque, hay algo que no me queda claro. (A esta hora de la madrugada no comprendo bien el tema)

En esa parte...
 Codigo Pawno:
1

bcrypt_hash("Que contraseña mas bonita", BCRYPT_COST, "OnPasswordHashed", "d", playerid);
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
Cuando se esta hasheando la contraseña del usuario. ¿Lo de 'contraseña mas...' a que hace referencia? Es una pregunta tonta, pero es solo para tener en claro lo demás que ya entendí.
KaizerHind escribió:
10 Sep 2018 04:09
Excelente y grandioso aporte eh, aunque, hay algo que no me queda claro. (A esta hora de la madrugada no comprendo bien el tema)

En esa parte...
 Codigo Pawno:
1

bcrypt_hash("Que contraseña mas bonita", BCRYPT_COST, "OnPasswordHashed", "d", playerid);
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
Cuando se esta hasheando la contraseña del usuario. ¿Lo de 'contraseña mas...' a que hace referencia? Es una pregunta tonta, pero es solo para tener en claro lo demás que ya entendí.
Si te fijas en la lista de funciones que puse:
 Codigo Pawno:
1

bcrypt_hash(key[], cost = 12, callback_name[], callback_format[] = "", {Float, _}:...);
  Cantidad de llaves: Abiertas(1)-Cerradas(1) | Lineas Totales: 1
Es el parámetro key, el cuál lo toma como una string. Sería la cadena que quieres hashear. Si usáis dialogos, pondríais la variable inputtext (lógicamente escapada con mysql_escape). Para hacer las pruebas, puedes poner una string ahí, que es lo que hice yo.

Un saludo -hi
Kemula escribió:
10 Sep 2018 03:58
Hola.

No tenía pensado hacer ningún aporte hoy, pero aquí estoy al final. La verdad es que no entiendo por qué, una buena parte de los servidores no almacena de forma segura los datos de los usuarios. Y lo peor no es solo eso, sino que muchas veces, para las contraseñas usa algoritmos de hashing bastante débiles o con colisiones. Véase MD5, o incluso SHA1.

Podríais argumentar que SHA256 es seguro, pero si decís eso, vuestro argumento es inválido.

Hoy en día, los algoritmos para hashear contraseñas considerados más seguros son:
  • Argon2
  • PBKDF2
  • scrypt
  • Bcrypt
Desafortunadamente, en SAMP no tenemos soporte para los otros. No pasa tampoco nada, ya que bcrypt es un algoritmo que va a seguir siendo de los más seguros a medio-largo plazo.

bcrypt para SAMP

El plugin que hoy os traigo es de lassir, y se llama bcrypt-samp, el cual es una implementación de bcrypt para samp.

Es asíncrona, ya que bcrypt consume bastante más potencia de computado que otros algoritmos más simples (e inseguros).


Instalación

Para instalarlo: Si hemos usado el primer método, tan solo incluímos ahora
 Codigo Pawno:
1

#include <bcrypt>
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
Si usamos el segundo, tendremos que colocar el plugin en su carpeta, y el include también en la suya.

Sus funciones

Funciones:
 Codigo Pawno:
1
2
3
4
5
6
7
8

bcrypt_hash(key[], cost = 12, callback_name[], callback_format[] = "", {Float, _}:...); // Manda un texto a encriptar.
bcrypt_get_hash(dest[]); // Función que será llamada en el callback para obtener hash
bcrypt_check(key[], hash[], callback_name[], callback_format[] = "", {Float, _}:...); // Manda una comprobación entre un hash y un texto
bool:bcrypt_is_equal(); // Función que se llama en el callback para comprobar si coincide el hash mandado y el texto
bool:bcrypt_needs_rehash(hash[], cost); // Para comprobar si necesita volver a ser hasheado la contraseña hasheada.
bcrypt_find_cost(time_target = 250); // Encontrar el costo estimado basado en tiempo en milisegundos.
bcrypt_debug(BCRYPT_DEBUG_LEVEL:level = BCRYPT_LOG_ERROR); // Nivel de debug.
bcrypt_set_thread_limit(value); // Establece un máximo de threads concurrentes para ser usados por el plugin.
  Cantidad de llaves: Abiertas(2)-Cerradas(2) | Lineas Totales: 8
En este tutorial solamente vamos a trabajar con las cuatro primeras funciones.

¿Cómo se usa?

Hashear una contraseña
Para hashear la contraseña de un usuario:
 Codigo Pawno:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <bcrypt>
#define BCRYPT_COST 12 // Este coste está bien. Ni consume mucho, ni es inseguro.

// En alguna parte de tu gamemode, como por ejemplo cuando el usuario en el registro introduce su contraseña
bcrypt_hash("micontraseña", BCRYPT_COST, "OnPasswordHashed", "d", playerid);

forward OnPasswordHashed(playerid);
public OnPasswordHashed(playerid) // El callback será llamado cuando termine el hasheo el plugin
{
	new hash[BCRYPT_HASH_LENGTH];
	bcrypt_get_hash(hash); // Almacena el hash en la variable hash, por lo que podemos usarla para guardar en la base de datos.
	
	printf("El hash para el jugador %d: %s", playerid, hash); // Esto se puede quitar, es solo par que veáis como funciona.
	return 1;
}
  Cantidad de llaves: Abiertas(1)-Cerradas(1) | Lineas Totales: 15
Comprobar si la contraseña es correcta
El código de bcrypt_check se podría poner por ejemplo, en los diálogos de login, cuando el usuario introduce su contraseña.
 Codigo Pawno:
1
2
3
4
5
6
7
8
9
10

bcrypt_check("micontraseña", "$2y$12$a250ZgU7rRlP8GC41eJLGeCDOTrr3yNTrEo3mzH8eNXqpCN9fhgOu",  "OnPasswordChecked", "d", playerid); // Donde va $2 y lo que continúa, sería el hash.

forward OnPasswordChecked(playerid);
public OnPasswordChecked(playerid)
{
	new bool:match = bcrypt_is_equal(); // Si match es verdadero, la contraseña será correcta. Si no, no lo será.

	printf("La contraseña introducida por el usuario %d: %s", (match) ? ("coincide") : ("no coincide")); // Esto se puede quitar, es solo par que veáis como funciona.
	return 1;
}
  Cantidad de llaves: Abiertas(1)-Cerradas(1) | Lineas Totales: 10

Créditos

A Lassir, por crear este maravilloso y útil plugin.
¿A mí? Supongo, por hacer este post.

Si tenéis dudas, podéis dejarlas por aquí. No lo veo un plugin complicado ni mucho menos, y creo que con los dos ejemplos que he dejado queda bastante claro su uso.

Un saludo -hi

Buen aporte,normalmente usaba SHA1 pero ahora usaré este.
Gracias Kemula.
BonerMap escribió:
10 Sep 2018 16:50
[...]

Buen aporte,normalmente usaba SHA1 pero ahora usaré este.
Gracias Kemula.
Me alegro de que te haya gustado/servido este aporte. Es muy importante que se dejen de usar algoritmos inseguros, y espero ver los futuros gamemodes que lance la gente implementando algo seguro como esto.

Si tienes preguntas o necesitas ayuda para implementarlo en tu gamemode, estamos por aquí para ayudar.

Un saludo -hi
Buen aporte, yo uso BCrypt para asegurar las contraseñas de los jugadores. ¡Hay que respetar la privacidad del usuario!
¿No seria así?
 Codigo Pawno:
1

printf("La contraseña introducida por el usuario %d: %s", playerid,(match) ? ("coincide") : ("no coincide"));
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
#Fede escribió:
13 Sep 2018 08:16
¿No seria así?
 Codigo Pawno:
1

printf("La contraseña introducida por el usuario %d: %s", playerid,(match) ? ("coincide") : ("no coincide"));
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
¡Síp!

Siempre me pasa lo mismo, el código está mal en el README.md del repositorio del creador -ops -sorry

Actualizado -hi
#Fede escribió:
13 Sep 2018 08:16
¿No seria así?
 Codigo Pawno:
1

printf("La contraseña introducida por el usuario %d: %s", playerid,(match) ? ("coincide") : ("no coincide"));
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
En realidad sería mejor así:
 Codigo Pawno:
1

printf("La contraseña introducida por el usuario %d: %s", playerid, (match) ? ("coincide") : ("no coincide"));
  Cantidad de llaves: Abiertas(0)-Cerradas(0) | Lineas Totales: 1
-laughing -laughing

Sobre el post:
Evitare desvirtuar el tema respecto a temas como "¿la comunidad de sa:mp merece tanta seguridad?"(entre otros claramente), e ire al grano:
BScript es(y estoy muy seguro de que puedo decir "y sera") el encriptado de datos mas seguro de SA:MP(y no digo esto porque me ahorra el trabajo de escribir un callback nuevo al finalizar el encriptado (? )


Muchas gracias por compatirlo en PawnScript Imagen

¿Quién está conectado?

En total hay 2 usuarios conectados :: 1 registrado, 0 ocultos y 1 invitado (basados en usuarios activos en los últimos 5 minutos)
La mayor cantidad de usuarios identificados fue 855 el 27 May 2018 00:03

Usuarios navegando por este Foro: Bing [Bot] y 1 invitado