Firma digital con Golang y RSA

Firma digital con Go y RSA

El día de hoy vamos a ver cómo firmar y verificar un mensaje con Golang y un par de claves RSA.

Es decir, por un lado veremos cómo firmar digitalmente un mensaje usando una clave privada y por otro lado vamos a ver cómo comprobar la autenticidad de dicho mensaje.

Recordemos que las firmas digitales tienen el propósito de comprobar la autenticidad de un mensaje, no de ocultarlo (de eso se encarga la criptografía).

Veamos entonces cómo firmar y verificar firmas con Go.

Sobre las claves

Vamos a usar un par de claves. De manera distinta a la criptografía asimétrica aquí vamos a firmar con la privada y distribuir la pública junto con el mensaje plano y firmado.

Puedes generar ese par de claves con openssl o usar tus propios métodos. Eso sí, deben ser claves de tipo RSA. Mira el siguiente tutorial para ver un ejemplo de claves:

Generar par de claves RSA con OpenSSL (privada y pública)

Parseando claves

En Go vamos a usar una rsa.PrivateKey y una rsa.PublicKey. Tenemos algunas funciones que van a convertir una string de clave en formato PEM a PrivateKey o PublicKey.

Las funciones no son mías. Quedan así:

Básicamente lo que nos permite es convertir una cadena de la clave RSA a un objeto de tipo rsa.PublicKey y rsa.PrivateKey.

Firmar mensaje

Ahora vamos a ver cómo firmar digitalmente con Go. Antes que nada, vamos a calcular la suma de verificación de dicho mensaje y firmar esa suma de verificación, así la longitud de datos se acorta.

No hay riesgo de seguridad al hacer esto, ya que te repito, al final solo estamos comprobando la autenticidad.

La firma se hace con rsa.SignPSS.

Por cierto, al momento de firmar se agrega una sal, así que aunque firmemos el mismo mensaje con la misma clave privada no obtendremos la misma salida pero la verificación seguirá funcionando.

Después de firmar, codificamos los bytes en base64. Esto solo es porque queremos representar el montón de bytes de una manera amigable, igual podríamos convertirlos a hexadecimal o cosas similares.

Sin importar la codificación que elijas al momento de firmar digitalmente con Go, asegúrate de hacer el proceso inverso al momento de verificar la firma.

Nota: obviamente para firmar vamos a usar la clave privada. Recuerda que esa clave no debe ser distribuida.

Verificar firma

Ahora vamos a verificar la autenticidad de un mensaje. Es decir, vamos a ver si la firma de un mensaje es válida exactamente para ese mensaje y para ello usaremos la clave pública que fue derivada de la privada.

Para verificar la firma usamos rsa.VerifyPSS. Si la función no devuelve ningún error (es decir, que err es nil) entonces la firma coincide.

Fíjate en que estoy decodificando de base64 en la línea 7, pues yo recibo la firma codificada en ese formato ya que así fue hecho al momento de firmar.

Poniendo todo junto

Veamos entonces estas dos funciones de firmar y verificar autenticidad con Golang.

En este caso lo hacemos en el mismo archivo porque es un ejemplo, pero en la vida real deberías dejar la clave privada y funciones de firma en un lugar, y la clave pública con funciones de verificación en otro.

El uso del código está en la función main.

Al compilarlo con go build y ejecutar el archivo compilado tenemos la siguiente salida de ejemplo:

Firma digital con Golang y RSA
Firma digital con Golang y RSA

En este caso el error es nil así que no hubo error, por lo tanto el mensaje fue firmado y verificado correctamente.

Recuerda que si vas a comprobar la firma necesitarás la clave pública, el mensaje en “texto plano” y la firma en base64.

Nota importante: aunque en el código la variable se llama mensajeSecreto me equivoqué al ponerle ese nombre. Te repito que aquí no vamos a encriptar ni esconder nada, solo vamos a firmar digitalmente ese mensaje con la clave privada.

Encantado de ayudarte


Estoy disponible para trabajar en tu proyecto, modificar el programa del post o realizar tu tarea pendiente, no dudes en ponerte en contacto conmigo.

No te pierdas ninguno de mis posts

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario