Skip to content

skabbio1976/jsoncrypt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

jsoncrypt

A Go package for encrypting and decrypting JSON data with a generic key-value store.

Features

  • Generic Store[T]: Type-safe key-value store that works with any Go struct
  • AES-256-GCM encryption: Industry-standard authenticated encryption
  • Argon2 key derivation: Secure password-based key derivation
  • Multiple key sources: Environment variables, files, or direct strings
  • Simple API: Easy to use encryption/decryption functions

Installation

go get github.com/skabbio1976/jsoncrypt

Quick Start

Basic Store Usage

package main

import (
    "fmt"
    "github.com/skabbio1976/jsoncrypt"
)

type Config struct {
    APIKey    string `json:"api_key"`
    Endpoint  string `json:"endpoint"`
    EnableSSL bool   `json:"enable_ssl"`
}

func main() {
    // Create a new store
    store := jsoncrypt.NewStore[Config]()

    // Add items
    store.Add("production", Config{
        APIKey:    "secret-key-123",
        Endpoint:  "https://api.example.com",
        EnableSSL: true,
    })

    // Get items
    if cfg, ok := store.Get("production"); ok {
        fmt.Printf("Config: %+v\n", cfg)
    }

    // List all keys
    names := store.ListNames()
    fmt.Println("Keys:", names)
}

Encrypt and Save with Password

// Save encrypted with password
password := "my-secure-password"
err := store.SaveEncryptedWithPassword("/tmp/config.enc", password)
if err != nil {
    panic(err)
}

// Load encrypted store
loaded, err := jsoncrypt.LoadEncryptedStoreWithPassword[Config]("/tmp/config.enc", password)
if err != nil {
    panic(err)
}

Using KeySource for Production

For production use, it's better to use KeySource instead of hardcoded passwords:

// Generate a key once and store it securely
key, err := jsoncrypt.GenerateEncryptionKey()
if err != nil {
    panic(err)
}
fmt.Println("Save this key securely:", key)

// Use environment variable
ks := jsoncrypt.KeySourceEnv("ENCRYPTION_KEY")

// Or use a key file
// ks := jsoncrypt.KeySourceFile("/secure/path/to/key")

// Or use direct key
// ks := jsoncrypt.KeySourceDirect(key)

// Save encrypted
err = store.SaveEncrypted("/var/data/config.enc", ks)
if err != nil {
    panic(err)
}

// Load encrypted
loaded, err := jsoncrypt.LoadEncryptedStore[Config]("/var/data/config.enc", ks)
if err != nil {
    panic(err)
}

String Encryption

You can also encrypt individual strings:

// With password
encrypted, err := jsoncrypt.EncryptStringWithPassword("sensitive data", "password123")
if err != nil {
    panic(err)
}

decrypted, err := jsoncrypt.DecryptStringWithPassword(encrypted, "password123")
if err != nil {
    panic(err)
}
fmt.Println("Decrypted:", decrypted)

// With KeySource
ks := jsoncrypt.KeySourceEnv("ENCRYPTION_KEY")
encrypted, err = jsoncrypt.EncryptString("sensitive data", ks)
if err != nil {
    panic(err)
}

decrypted, err = jsoncrypt.DecryptString(encrypted, ks)
if err != nil {
    panic(err)
}

Example: VCenter Credentials

Here's how to use jsoncrypt for storing vCenter credentials (the original use case):

package main

import (
    "fmt"
    "github.com/skabbio1976/jsoncrypt"
)

type Credential struct {
    Server   string `json:"server"`
    Username string `json:"username"`
    Password string `json:"password"`
    Insecure bool   `json:"insecure"`
}

func main() {
    // Create credential store
    store := jsoncrypt.NewStore[Credential]()

    // Add credentials
    store.Add("vcenter-prod", Credential{
        Server:   "vcenter.example.com",
        Username: "admin@vsphere.local",
        Password: "super-secret",
        Insecure: false,
    })

    store.Add("vcenter-dev", Credential{
        Server:   "vcenter-dev.example.com",
        Username: "admin@vsphere.local",
        Password: "dev-password",
        Insecure: true,
    })

    // Save encrypted with KeySource
    ks := jsoncrypt.KeySourceEnv("VCENTER_ENCRYPTION_KEY")
    err := store.SaveEncrypted("/etc/vcenter/credentials.enc", ks)
    if err != nil {
        panic(err)
    }

    // Later, load credentials
    loaded, err := jsoncrypt.LoadEncryptedStore[Credential]("/etc/vcenter/credentials.enc", ks)
    if err != nil {
        panic(err)
    }

    // Use credentials
    if cred, ok := loaded.Get("vcenter-prod"); ok {
        fmt.Printf("Connecting to %s as %s\n", cred.Server, cred.Username)
    }

    // List all stored credentials
    fmt.Println("Available credentials:", loaded.ListNames())
}

Security Considerations

  • Key Storage: Never hardcode encryption keys. Use environment variables, secure key files, or a key management service.
  • File Permissions: Encrypted files are created with 0600 permissions (owner read/write only).
  • Argon2 Parameters: Uses conservative parameters (time=2, memory=64MB, threads=1) suitable for most applications.
  • AES-256-GCM: Provides both confidentiality and authenticity.
  • Random Salts: Each encryption uses a unique random salt, preventing rainbow table attacks.

API Reference

Store[T]

  • NewStore[T]() *Store[T] - Create a new empty store
  • Add(name string, item T) - Add or update an item
  • Get(name string) (T, bool) - Get an item by name
  • Delete(name string) - Remove an item
  • ListNames() []string - Get all keys sorted alphabetically
  • SavePlaintext(path string) error - Save as unencrypted JSON
  • SaveEncrypted(path string, ks KeySource) error - Save encrypted with KeySource
  • SaveEncryptedWithPassword(path string, password string) error - Save encrypted with password

Functions

  • LoadPlaintextStore[T](path string) (*Store[T], error) - Load unencrypted store
  • LoadEncryptedStore[T](path string, ks KeySource) (*Store[T], error) - Load encrypted store with KeySource
  • LoadEncryptedStoreWithPassword[T](path string, password string) (*Store[T], error) - Load encrypted store with password
  • EncryptString(plaintext string, ks KeySource) (string, error) - Encrypt a string with KeySource
  • DecryptString(encrypted string, ks KeySource) (string, error) - Decrypt a string with KeySource
  • EncryptStringWithPassword(plaintext string, password string) (string, error) - Encrypt with password
  • DecryptStringWithPassword(encrypted string, password string) (string, error) - Decrypt with password
  • GenerateEncryptionKey() (string, error) - Generate a random 32-byte hex key

KeySource

  • KeySourceEnv(name string) KeySource - Read key from environment variable
  • KeySourceFile(path string) KeySource - Read key from file
  • KeySourceDirect(secret string) KeySource - Use provided string as key

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages