decompiling me

Java, groovy, android y otras cosas que gustan a desarrolladores

Seguridad en BitCoin

Bitcoins fisicos

Fotografia de Antana

En el anterior artículo de esta serie se explicaron las bases sobre las que funciona la criptomoneda llamada BitCoin. Ahora nos adentramos en algunos detalles que sostienen la seguridad del protocolo BitCoin. Sirve para que aquellos que quieran comprar BitCoin sepan si será fácil o difícil que se los roben.

Éste es el segundo artículo de una serie de tres. Esta serie pretende explicar, sin necesidad de tener conocimientos técnicos, cómo funcionan los BitCoins, sus fortalezas y debilidades. Al final de la serie estarás preparado para saber si debes convertirte en un minero a tiempo completo o no.

Quién evita que roben mis bitcoins

No hay policía en los bitcoins. Todos los pares de la red son iguales, todos pueden ver la misma cadena de bloques, todos pueden modificarla y todos siguen las mismas reglas para modificarla.

Se puede pensar que al no existir un control central sería muy fácil que alguien manipulara la cadena de bloques para conseguir beneficiarse, dicho de otro modo, hackear el wallet para robar bitcoins. Los detalles de la implementación de BitCoin evitan que esto ocurra o pueda ocurrir en el futuro.

Antes de hablar de estos detalles es importante conocer los cimientos en los que se basan la seguridad en BitCoin: el cifrado de clave pública y las funciones de suma de comprobación.

Cifrado de clave pública

El cifrado de un texto consiste en convertirlo en otro texto, con la particularidad de que hay una forma de tomar este otro texto y convertirlo de nuevo al texto original. Al primer paso se le llama encriptación y al segundo desencriptación. Normalmente la encriptación y desencriptación requieren de una clave que solo deben conocer aquellas personas que encriptan y desencriptan el texto.

Si fueran funciones matemáticas podríamos escribir ésto:

encriptar(texto-en-claro, clave) -> texto-cifrado
desencriptar(texto-cifrado, clave) -> texto-en-claro

BitCoin utiliza un tipo de cifrado llamado de clave pública para asegurar que los bloques de la cadena de bloques no son modificados. En este caso la función para encriptar y desencriptar está hecha de tal manera que si se encripta con una clave llamada pública solo se puede desencriptar con una clave llamada privada y viceversa. Es decir:

encriptar(texto-en-claro, clave-publica) -> texto-cifrado
desencriptar(texto-cifrado, clave-privada) -> texto-en-claro

y
encriptar(texto-en-claro, clave-privada) -> texto-cifrado desencriptar(texto-cifrado, clave-publica) -> texto-en-claro

Función de suma de comprobación

En ocasiones se necesita un identificador único para un texto. Hay funciones matemáticas que cumplen la característica en las que dado un texto (de cualquier longitud) se puede generar un número que lo identifica unívocamente. Cualquier texto con la más mínima variación sobre el original generará un número distinto.

suma-comprobación(texto1) -> hash1
suma-comprobación(texto2) -> hash2

Si se quiere comprobar si dos textos son iguales solo es necesario comprobar sus sumas de comprobación o igual, es decir, si la suma de comprobación de texto1 es igual a la suma de comprobación de texto2 entonces texto1 y texto2 son iguales.

Ahora podemos ver cómo estos mecanismos matemáticos nos aseguran que es muy difícil robar bitcoins.

Transferencia entre dos pares

Cada wallet tiene (al menos) una dirección. Una dirección bitcoin no es solo un identificador a donde enviar o en donde recibir transferencias, sino algo más complejo.

Cada dirección dentro del wallet tiene una clave privada y una clave pública. Imaginemos un bloque con este texto:

direccion-1234 transfiere 1 bitcoin a la direccion-6789

Si lo codificamos con la clave privada asociado a la dirección direccion-1234 obtendremos un texto ilegible. Usando un software de desencriptación y la clave pública de direccion-1234 se podrá volver a reconstruir el bloque original, con la seguridad de que solo pudo ser codificado por el propietario de la clave privada. Como su propio nombre indica, la clave privada debe ser conocida solo por el propietario de la dirección direccion-1234, mientras que la clave pública puede ser conocida por cualquiera.

Por otro lado, el receptor podría verse tentado de modificar el bloque recibido para cambiar la cantidad que recibe. Para evitar esto antes de enviar el bloque, el emisor calcula una suma de comprobación (checksum) del bloque y encripta el resultado con su clave privada. Al resultado de este proceso se le llama firma.

Así pues, la forma en que dos pares dentro de la red BitCoin realizan una transferencia sigue estos pasos:

  • el emisor de la transferencia crea un bloque, por ejemplo:

    direccion-1234 transfiere 1 bitcoin a la direccion-6789

  • el emisor calcula el checksum del bloque:

    direccion-1234 transfiere 1 bitcoin a la direccion-6789, checksum=be099a75a207333a69b6c6bc7684f46f

  • el emisor encripta el checksum con su clave privada y crea la firma:

    direccion-1234 transfiere 1 bitcoin a la direccion-6789, firma=xskdkdifhekcid

  • el emisor hace llegar el bloque y la firma al receptor (en este caso la direccion-6789).

  • el receptor recibe el bloque y calcula por su cuenta el checksum.

  • el receptor recupera la clave pública de la dirección del emisor.

  • el receptor desencripta con la clave pública la firma y comprueba si el texto descodificado se corresponde con el checksum que él ha calculado por su cuenta.

Con este sistema ni el emisor puede rechazar una transferencia enviada ni el receptor puede modificar una transferencia recibida:

  • Si el emisor repudia la transferencia, el receptor puede demostrar que el emisor firmó la suma de comprobación con su clave privada.
  • Si el receptor modifica la transferencia nunca podrá firmar la suma de comprobación sin la clave privada, que solo es accesible para el emisor.

El problema del doble pago

Si la red BitCoin se limitara a dos pares intercambiando transferencias, todos los problemas se acabarían aquí. Pero la red BitCoin puede estar formada por un número indeterminado de pares. Al haber varios miembros en esta red aparece el problema del doble pago:

  • al emisor con la dirección direccion-1234 se le ocurre crear una segunda dirección: direccion-1234-b

  • el receptor recibe una transferencia

      direccion-1234 transfiere 1 bitcoin a la direccion-6789, firma=xskdkdifhekcid
  • como está firmada por el emisor, la acepta y piensa que la transacción se completó.

  • en el mismo momento el emisor envía transferencia otra dirigida a su segunda dirección.

      direccion-1234 transfiere 1 bitcoin a la direccion-1234-b, firma=y5xd0dyftescsm

Con esta segunda transferencia el emisor trata de recuperar los bitcoins gastados en la primera. Este tipo de conflictos se pueden resolver teniendo un “contador universal” de todas las transacciones enviadas. Antes de emitir cualquier transacción tendríamos que depositar nuestra confianza en un miembro de la red que asegurara que todas las transacciones se emiten en cierto orden.

BitCoin evita en su diseño cualquier punto de fallo único. No existe ningún miembro de la red con esos poderes, por lo que se ha creado un complejo sistema para evitar delegar responsabilidades a una única autoridad. La idea es la siguiente:

  • cualquier emisor envía la transferencia firmada al receptor y a cualquier par de la red que quiera validar la transacción.
  • para validar una transacción hay que calcular otra suma de comprobación y su cómputo tendrá una duración aproximada de 10 minutos.
  • solo después de realizar la validación, el bloque se puede añadir a la cadena de bloques.
  • el primer par que valide el bloque y lo prepare para añadirlo a la cadena gana la competición establecida con el resto de validadores.
  • la primera transacción validada es la que se añade a la cadena de bloques. La otra será desestimada, aunque algún validador consiga encontrar su checksum.
  • los validadores que añaden un nuevo bloque a la cadena de bloques se quedan con una pequeña cantidad de bitcoins por su trabajo.

A los validadores que realizan estos cálculos pesados se los llama mineros (miners). Cualquier par de la red BitCoin puede ejercer de minero si está dispuesto a gastar su tiempo en estas pruebas de trabajo (proof-of-work). A cambio serán recompensados con cierta cantidad de bitcoins.

Varios mineros pueden trabajar simultáneamente para minar (o validar) las dos transferencias de ejemplo anterior. El proceso de minado está ajustado para tardar aproximadamente 10 minutos, pero el tiempo de minado es muy variable. Solo una transferencia será la que se añada a la cadena de bloques. El minado de la otra llegara después y será ignorada, con lo cual o un bitcoin es recibido en direccion-6789 o en direccion-1234-b, pero nunca se añaden a la cadena de bloques las dos transacciones.

En el próximo artículo entraremos en más detalles sobre el proceso de minado y aclararemos qué hace falta para ser un minero de éxito en BitCoin.