Sling Academy
Home/Golang/Creating and Verifying Digital Signatures in Go

Creating and Verifying Digital Signatures in Go

Last updated: November 27, 2024

Introduction

Digital signatures are a crucial aspect of modern security practices, ensuring the authenticity and integrity of digital messages or documents. In this article, we will walk through the process of creating and verifying digital signatures in Go, also known as Golang. We'll explore Go's crypto libraries to implement these mechanisms.

Setting Up

Ceate a new directory for your project:

mkdir digital-signatures
cd digital-signatures

Generating Keys

The first step in creating a digital signature is generating a pair of public and private keys. We'll use the crypto/rsa and crypto/rand packages to create a 2048-bit RSA key pair.

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "log"
    "os"
)

func generateKeys() (*rsa.PrivateKey, *rsa.PublicKey) {
    privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        log.Fatalf("Error generating keys: %v", err)
    }
    return privateKey, &privateKey.PublicKey
}

func savePEMKey(fileName string, key *rsa.PrivateKey) {
    file, err := os.Create(fileName)
    if err != nil {
        log.Fatalf("Error saving key: %v", err)
    }
    defer file.Close()

    pem.Encode(file, &pem.Block{
        Type:  "RSA PRIVATE KEY",
        Bytes: x509.MarshalPKCS1PrivateKey(key),
    })
}

This code defines a function to generate an RSA private and public key. Another function is provided to save the private key in a file in PEM format for later use.

Creating Digital Signatures

With the keys generated, the next step is to create a digital signature using your private key. We will leverage the SHA256 hashing algorithm to create a signature from our message.

import (
    "crypto/sha256"
    "crypto"
)

func signMessage(message string, privateKey *rsa.PrivateKey) []byte {
    hashed := sha256.Sum256([]byte(message))
    signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:])
    if err != nil {
        log.Fatalf("Error signing message: %v", err)
    }
    return signature
}

This function, signMessage, takes a message and a privateKey, hashes the message using SHA256, and subsequently creates a signature for this hash using the private key.

Verifying Digital Signatures

Finally, to verify a digital signature, you'll use the associated public key along with the signature itself. Here's how you can do that with Go:

func verifySignature(message string, signature []byte, publicKey *rsa.PublicKey) bool {
    hashed := sha256.Sum256([]byte(message))
    err := rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], signature)
    if err != nil {
        log.Printf("Failed to verify signature: %v", err)
        return false
    }
    return true
}

func main() {
    privateKey, publicKey := generateKeys()

    message := "This is a test message"
    signature := signMessage(message, privateKey)

    if verifySignature(message, signature, publicKey) {
        log.Println("Signature verified successfully!")
    } else {
        log.Println("Failed to verify signature.")
    }
    savePEMKey("private.pem", privateKey)
}

In the verifySignature function, we check the signature using the corresponding public key. The main function brings it all together, generating keys, signing a message, and verifying the signature.

Conclusion

In this article, we've explored how to generate keys, create digital signatures, and verify them using Go's built-in libraries. The practical skills you've gained form the basis for digital message authentication and integrity verification in software applications. Always remember to keep your private keys secure, as their compromise would lead to a breakdown of the signing protocol's effectiveness.

Next Article: Encrypting Data with ChaCha20-Poly1305 in Go

Previous Article: Using SHA-256 for Hashing in Go: A Practical Guide

Series: Cryptography and Security in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant