A Go library for interfacing with YubiKeys using the PIV (Personal Identity Verification) standard.
- YubiKey Detection: Automatically scan and detect available YubiKeys
- Certificate Management: Retrieve and save certificates from YubiKey slots
- Key Generation: Generate RSA key pairs directly on the YubiKey
- Digital Signing: Sign data using private keys stored on the YubiKey
- Slot Management: List and manage different PIV slots (Authentication, Signature, Key Management, Card Authentication)
- Go 1.21 or later
- A YubiKey with PIV functionality enabled
- PC/SC Smart Card service running (on macOS:
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.securityd.plist)
go mod tidypackage main
import (
"log"
"github.com/go-piv/piv-go"
)
func main() {
// Create YubiKey manager
manager := NewYubiKeyManager()
// Detect available YubiKeys
err := manager.DetectYubiKeys()
if err != nil {
log.Fatalf("Failed to detect YubiKeys: %v", err)
}
// Connect to the first YubiKey
yubikey, err := manager.ConnectToYubiKey(manager.cards[0])
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer yubikey.Close()
// List available slots
manager.ListSlots(yubikey)
}// Get certificate from authentication slot
cert, err := manager.GetCertificate(yubikey, piv.SlotAuthentication)
if err != nil {
log.Printf("No certificate: %v", err)
} else {
log.Printf("Certificate subject: %s", cert.Subject.CommonName)
// Save certificate to file
err = manager.SaveCertificateToFile(cert, "cert.pem")
if err != nil {
log.Printf("Failed to save: %v", err)
}
}// Generate new RSA key pair (requires PIN)
pin := "123456" // Default PIN
publicKey, err := manager.GenerateKeyPair(yubikey, piv.SlotSignature, pin)
if err != nil {
log.Printf("Failed to generate key: %v", err)
} else {
log.Printf("Generated public key: %T", publicKey)
}// Sign data using stored private key
data := []byte("Hello, YubiKey!")
signature, err := manager.SignData(yubikey, piv.SlotSignature, data, pin)
if err != nil {
log.Printf("Failed to sign: %v", err)
} else {
log.Printf("Signature generated: %x", signature)
}The YubiKey supports four main PIV slots:
- Authentication (
piv.SlotAuthentication): Used for authentication operations - Signature (
piv.SlotSignature): Used for digital signatures - Key Management (
piv.SlotKeyManagement): Used for key management operations - Card Authentication (
piv.SlotCardAuthentication): Used for card-to-card authentication
- PIN Protection: Most operations require a PIN (default: 123456)
- Management Key: Required for key generation (default: 010203040506070801020304050607080102030405060708)
- Physical Security: Always keep your YubiKey physically secure
- PIN Management: Change default PINs before production use
- Ensure YubiKey is properly inserted
- Check that PC/SC service is running
- Verify YubiKey has PIV applet enabled
- Try reinserting the YubiKey
- Check USB connection
- Ensure no other applications are using the YubiKey
- Default PIN is
123456 - PIN can be changed using YubiKey Manager
- After 3 failed attempts, PIN is blocked
github.com/go-piv/piv-go: PIV protocol implementationgithub.com/sirupsen/logrus: Structured logging
MIT License - see LICENSE file for details.