How to generate VAPID keys with Go

VAPID (Voluntary Application Server Identification for Web Push) keys are used in the context of push notifications to authenticate the origin server and allow the sending of push messages to clients. In this article, we will see how to generate VAPID keys using the Go programming language.

Prerequisites

  1. Go Installation: Make sure you have Go installed on your system. You can download it from golang.org.
  2. Module github.com/cespare/xxhash: We will use this module for hashing.
  3. Familiarity with basic concepts of push notifications and the crypto/elliptic library.

Create a new directory for your project and initialize a new Go module:


mkdir vapid-keygen
cd vapid-keygen
go mod init vapid-keygen

Although we won't use many external dependencies for this example, it's good practice to install the necessary ones:


go get -u github.com/cespare/xxhash

Create a main.go file and add the following code:


package main

import (
    "crypto/elliptic"
    "crypto/ecdsa"
    "crypto/rand"
    "encoding/base64"
    "fmt"
    "log"
)

func generateVAPIDKeys() (string, string, error) {
    // Elliptic curve P-256
    curve := elliptic.P256()
    privateKey, err := ecdsa.GenerateKey(curve, rand.Reader)
    if err != nil {
        return "", "", err
    }

    // Extracting the public key
    publicKey := append(privateKey.PublicKey.X.Bytes(), privateKey.PublicKey.Y.Bytes()...)

    // Base64 encoding of the keys
    publicKeyBase64 := base64.RawURLEncoding.EncodeToString(publicKey)
    privateKeyBase64 := base64.RawURLEncoding.EncodeToString(privateKey.D.Bytes())

    return publicKeyBase64, privateKeyBase64, nil
}

func main() {
    pubKey, privKey, err := generateVAPIDKeys()
    if err != nil {
        log.Fatalf("Error generating VAPID keys: %v", err)
    }

    fmt.Printf("Public Key: %s\n", pubKey)
    fmt.Printf("Private Key: %s\n", privKey)
}

This code generates a key pair using the P-256 elliptic curve and encodes them in base64 URL-safe format.

Once the keys are generated, they can be used to authenticate push notifications. Below is an example of how to use these keys with the web-push library to send push notifications:


package main

import (
    "github.com/SherClockHolmes/webpush-go"
    "log"
)

func main() {
    sub := &webpush.Subscription{
        Endpoint: "https://fcm.googleapis.com/fcm/send/...",
        Keys: webpush.Keys{
            Auth: "your_auth_key",
            P256dh: "your_p256dh_key",
        },
    }

    resp, err := webpush.SendNotification([]byte("Test message"), sub, &webpush.Options{
        VAPIDPublicKey:  "your_public_key",
        VAPIDPrivateKey: "your_private_key",
        VAPIDSubject:    "mailto:example@yourdomain.org",
    })
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
}

Conclusion

In this article, we have seen how to generate VAPID keys using Go. These keys are essential for authenticating push notifications and ensuring secure communication between the server and the client. With the generated keys, you can now proceed to implement your push notification solution.

Back to top