This simple library provides tools for work with private and public keys using RSA as JWK. The Library allows generating, save and load crypto keys pair based on RSA algorithm. JWKS usually use asymmetric encryption keys pair where public key (using in JWKS) for validate the JWT tokens which signed with private part of keys. A public key can be placed at different service or server for validate JWT signature.
The Library write in Go and you can either embed to golang projects or use as a standalone application.
Main items of this library is crypto keys pair. You can generate they or load from some storage. Library supports both of this way (in currently support only RSA keys).
Init keys pair with NewKeysfor create Keys instance.
Constructor can accept two options:
-
Storage - this is interface which has
LoadandSavemethod. They define where keys will be stored and load from. User can use pre-defined storageFileprovider instoragepackage. By default, this option is undefined and new generated keys will store in memory only. StorageFileprovider required path to private and public keys. -
BitSize - defined size for crypto key which will be generated. Option accept
intvalue By default - 2048.
After Keys inited user should either Generate new key pair or Load from storage provider if keys doesn't exist in storage yet.
keys,err:=NewKeys() // if storage option undefined key pair store in memory
if err!=nil {
// handle error
}
// Generate new keys pair if need
if err=keys.Generate();err!=nil {
// handle error
}
err,jwk:=keys.JWK()
if err!=nil {
// handle error
}
fmt.Println(jwk.ToString())A after execute code above you get result like this:
{
"kty": "RSA",
"kid": "oI4f",
"use": "sig",
"alg": "RS256",
"n": "n5Y24DhSDIKIN6tJbrOMxfZpoedvAIAA5vKv...",
"e": "AQAB"
}Example with options:
// NewFileStorage accept rootPath, privateKey and publicKey names params
fs := storage.NewFileStorage("./","test_private.key", "test_public.key")
keys, err := NewKeys(Storage(fs))
// if storage provider hasn't keys pair yet user can generate they
// after generated key pair will be save to defined storage
if err=keys.Generate();err!=nil {
// handle error
}
// Load key pair from storage provider
if err=keys.Load();err!=nil {
// handle error
}
err,jwk:=keys.JWK()
if err!=nil {
// handle error
}Keys has method CreateCAROOT for create Certificate Authority (CA) file with generated keys pair
// create Keys instance
keys, err := NewKeys()
if err=keys.Load();err!=nil {
// handle error
}
// create certificate data
ca := &x509.Certificate{
SerialNumber: big.NewInt(2019),
Subject: pkix.Name{
Organization: []string{"TEST, INC."},
Country: []string{"RU"},
Province: []string{""},
Locality: []string{"Krasnodar"},
StreetAddress: []string{"Krasnaya"},
PostalCode: []string{"350000"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(5, 0, 0),
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
}
// add Subject Alternative Name for requested IP and Domain
// it prevent error with untrusted certificate for client request
// https://oidref.com/2.5.29.17
ca.IPAddresses = append(ca.IPAddresses, net.ParseIP("127.0.0.1"))
ca.IPAddresses = append(ca.IPAddresses, net.ParseIP("::"))
ca.DNSNames = append(ca.DNSNames, "localhost")
// generate RSA keys pair (private and public)
if err=keys.Generate();err!=nil {
// handle error
}
// create CA certificate for created keys pair
if err = keys.CreateCAROOT(ca); err != nil {
return nil, nil, err
}
// if storage provider defined user should call Save function for store certificate and keys filesFull example with web service usage see here example
The code still under development. Until v1.x released the API & protocol may change.