horcrux

package module
v0.0.0-...-a818491 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 7, 2014 License: MIT Imports: 7 Imported by: 0

README

horcrux

Build Status

A pure Go implementation of security question style password recovery that preserves end-to-end cryptographic security.

For documentation, check godoc.

Documentation

Overview

Package horcrux provides security question style password recovery while preserving end-to-end cryptographic security.

Given N pairs of security questions and answers, the secret is split using Shamir's Secret Sharing algorithm into N shares, one for each question. A 256-bit key is derived from the answer to each question using scrypt, and the share is then encrypted with that key using ChaCha20Poly1305.

To recover the secret given K of N answers, the secret keys are re-derived and the shares are decrypted and combined.

This package has not been audited by cryptography or security professionals.

Example
secret := []byte("my favorite password")
questions := map[string]string{
	"What's your first pet's name?":     "Spot",
	"What's your least favorite food?":  "broccoli",
	"What's your mother's maiden name?": "Hernandez",
	"What's your real name?":            "Rumplestiltskin",
}

// Split into four fragments, any two of which can be combined to recover
// the secret.
frags, err := Split(secret, questions, 2, 2<<14, 8, 1)
if err != nil {
	fmt.Println(err)
	return
}

// Answer two of the security questions.
answers := make([]Answer, 2)
for i := range answers {
	answers[i] = Answer{
		Fragment: frags[i],
		Answer:   questions[frags[i].Question],
	}
}

// Recover the original secret.
s, err := Recover(answers)
if err != nil {
	fmt.Println(err)
	return
}

fmt.Println(string(s))
Output:

my favorite password

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Recover

func Recover(answers []Answer) ([]byte, error)

Recover combines the given answers and returns the original secret or an error.

Types

type Answer

type Answer struct {
	Fragment        // Fragment is the previously-encrypted fragment.
	Answer   string // Answer is the answer to the security question.
}

Answer is an encrypted fragment of the secret, plus the answer to the security question.

func (Answer) String

func (f Answer) String() string

type Fragment

type Fragment struct {
	ID byte // ID is a unique identifier for the fragment.
	K  int  // K is the number of fragments required to recover the secret.
	N  int  // N is the scrypt iteration parameter.
	R  int  // R is the scrypt memory parameter.
	P  int  // P is the scrypt parallelism parameter.

	Question string // Question is the security question.
	Nonce    []byte // Nonce is the random nonce used for encryption.
	Salt     []byte // Salt is the random salt used for scrypt.
	Value    []byte // Value is the encrypted share.
}

Fragment is an encrypted fragment of the secret associated with a security question.

func Split

func Split(secret []byte, questions map[string]string, k, n, r, p int) ([]Fragment, error)

Split splits the given secret into encrypted fragments based on the given security questions. k is the number of fragments required to recover the secret. n is the scrypt iteration parameter, and should be set fairly high due to the low entropy of most security question answers (recommended: 2<<14). r is the scrypt memory parameter (recommended: 8). p is the scrypt parallelism parameter (recommended: 1). Returns either a slice of fragments or an error.

func (Fragment) String

func (f Fragment) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL