atoll

package module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Feb 26, 2023 License: MIT Imports: 12 Imported by: 5

README

Atoll

PkgGoDev Go Report Card

Atoll is a library for generating cryptographically secure and highly random secrets.

Features

  • High level of randomness
  • Well tested
  • No dependencies
  • Input validation
  • Secret sanitization
  • Include characters/words/syllables in random positions
  • Exclude any undesired character/word/syllable
  • Password:
    • 5 different levels (custom levels can be used as well)
    • Enable/disable character repetition
  • Passphrase:
    • Choose between Word, Syllable or No list options to generate the passphrase
    • Custom word/syllable separator

Installation

go get -u github.com/GGP1/atoll

Usage

package main

import (
    "fmt"
    "log"

    "github.com/GGP1/atoll"
)

func main() {
    p := &atoll.Password{
        Length: 16,
        Levels: []int{atoll.Lower, atoll.Upper, atoll.Digit},
        Include: "a&1",
        Repeat: true,
    }
    password, err := atoll.NewSecret(p)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(password)
    // 1VOKM7mNA6w&oIan

    p1 := &atoll.Passphrase{
        Length: 7,
        Separator: "/",
        List: atoll.NoList,
    }
    passphrase, err := atoll.NewSecret(p1)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(passphrase)
    // aei/jwyjidaasres/duii/rscfiotuuckm/ydsiacf/ora/yywu
}

Head over example_test.go to see more examples.

Documentation

Password levels

Atoll guarantees that the password will contain at least one of the characters of each level selected (except Space1), only if the length of the password is higher than the number of levels.

  1. Lowecases (a, b, c...)
  2. Uppercases (A, B, C...)
  3. Digits (1, 2, 3...)
  4. Space
  5. Special (!, $, %...)
Passphrases options

Atoll offers 3 ways of generating a passphrase:

  • Without a list (NoList): generates random numbers that determine the word length (between 3 and 12 letters) and if the letter is either a vowel or a constant. Note that using a list makes the potential attacker job harder.

  • With a Word list (WordList): random words are taken from a 18,235 long word list.

  • With a Syllable list (SyllableList): random syllables are taken from a 10,129 long syllable list.

Randomness

Randomness is a measure of the observer's ignorance, not an inherent quality of a process.

Atoll uses the "crypto/rand" package to generate cryptographically secure random numbers.

Entropy

Entropy is a measure of the uncertainty of a system. The concept is a difficult one to grasp fully and is confusing, even to experts. Strictly speaking, any given passphrase has an entropy of zero because it is already chosen. It is the method you use to randomly select your passphrase that has entropy. Entropy tells how hard it will be to guess the passphrase itself even if an attacker knows the method you used to select your passphrase. A passphrase is more secure if it is selected using a method that has more entropy. Entropy is measured in bits. The outcome of a single coin toss -- "heads or tails" -- has one bit of entropy. - Arnold G. Reinhold.

Entropy = log2(poolLength ^ secretLength)

The French National Cybersecurity Agency (ANSSI) recommends secrets having a minimum of 100 bits when it comes to passwords or secret keys for encryption systems that absolutely must be secure. In fact, the agency recommends 128 bits to guarantee security for several years. It considers 64 bits to be very small (very weak); 64 to 80 bits to be small; and 80 to 100 bits to be medium (moderately strong).

Keyspace

Keyspace is the set of all possible permutations of a key. On average, half the key space must be searched to find the solution.

Keyspace = poolLength ^ secretLength

Seconds to crack

When calculating the seconds to crack the secret what is considered is a brute force attack. Dictionary and social engineering attacks (like shoulder surfing. pretexting, etc) are left out of consideration.

The time taken in seconds by a brute force attack to crack a secret is calculated by doing keyspace / guessesPerSecond where the guesses per second is 1 trillon2.

In 2019 a record was set for a computer trying to generate every conceivable password. It achieved a rate faster than 100 billion guesses per second.

1: If the level Space is used or the user includes a space it isn't 100% guaranteed that the space will be part of the secret, as it could be at the end or the start of the password and it would be deleted and replaced by the sanitizer.

2: This value may be changed in the future.

License

Atoll is licensed under the MIT license.

Documentation

Overview

Package atoll is a secret generator that makes use of the crypto/rand package to generate cryptographically secure numbers and offer a high level of randomness.

Index

Examples

Constants

View Source
const (
	Lower   = Level("abcdefghijklmnopqrstuvwxyz")
	Upper   = Level("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
	Digit   = Level("0123456789")
	Space   = Level(" ")
	Special = Level("&$%@#|/\\=\"*~^`'.?!,;:-+_(){}[]<>")
)

Password level.

Variables

This section is empty.

Functions

func Keyspace added in v0.3.0

func Keyspace(secret Secret) float64

Keyspace returns the set of all possible permutations of the generated key (poolLength ^ keyLength).

On average, half the key space must be searched to find the solution (keyspace/2).

Example
package main

import (
	"fmt"

	"github.com/GGP1/atoll"
)

func main() {
	p := &atoll.Password{
		Length: 6,
		Levels: []atoll.Level{atoll.Lower},
		Repeat: false,
	}

	fmt.Println(atoll.Keyspace(p))
}
Output:

3.089157759999998e+08

func NewPassphrase

func NewPassphrase(length uint64, l list) ([]byte, error)

NewPassphrase returns a random passphrase.

Example
package main

import (
	"fmt"
	"log"

	"github.com/GGP1/atoll"
)

func main() {
	passphrase, err := atoll.NewPassphrase(5, atoll.NoList)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(passphrase)
	// Example output:
	// ynuafnezm hvoq asruso jvoe psiro
}
Output:

func NewPassword

func NewPassword(length uint64, levels []Level) ([]byte, error)

NewPassword returns a random password.

Example
package main

import (
	"fmt"
	"log"

	"github.com/GGP1/atoll"
)

func main() {
	password, err := atoll.NewPassword(16, []atoll.Level{atoll.Digit, atoll.Lower})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(password)
	// Example output:
	// ?{{5Rt%r3OrE}7?z
}
Output:

func NewSecret added in v0.2.0

func NewSecret(secret Secret) ([]byte, error)

NewSecret generates a new secret.

func NoList

func NoList(p *Passphrase, length int)

NoList generates a random passphrase without using a list, making the potential attacker work harder.

func SecondsToCrack added in v0.3.0

func SecondsToCrack(secret Secret) float64

SecondsToCrack returns the time taken in seconds by a brute force attack to crack the secret.

It's assumed that the attacker can perform 1 trillion guesses per second.

func SyllableList

func SyllableList(p *Passphrase, length int)

SyllableList generates a passphrase using a syllable list (10,129 long).

func WordList

func WordList(p *Passphrase, length int)

WordList generates a passphrase using a wordlist (18,325 long).

Types

type Level added in v0.4.0

type Level string

Level represents a determined group of characters.

type Passphrase

type Passphrase struct {
	// List used to generate the passphrase.
	List list
	// Words separator.
	Separator string

	// Words that will be part of the passphrase.
	Include []string
	// Words that won't be part of the passphrase.
	Exclude []string
	// Number of words in the passphrase.
	Length uint64
	// contains filtered or unexported fields
}

Passphrase represents a sequence of words/syllables with a separator between them.

Example
package main

import (
	"fmt"
	"log"

	"github.com/GGP1/atoll"
)

func main() {
	p := &atoll.Passphrase{
		Length:    8,
		Separator: "&",
		List:      atoll.WordList,
		Include:   []string{"atoll"},
		Exclude:   []string{"watermelon"},
	}

	passphrase, err := atoll.NewSecret(p)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(passphrase)
	// Example output:
	// eremite&align&coward&casing&atoll&maximum&user&adult
}
Output:

func (*Passphrase) Entropy

func (p *Passphrase) Entropy() float64

Entropy returns the passphrase entropy in bits.

If the list used is "NoList" the secret must be already generated.

func (*Passphrase) Generate

func (p *Passphrase) Generate() ([]byte, error)

Generate generates a random passphrase.

type Password

type Password struct {

	// Characters that will be part of the password.
	Include string
	// Characters that won't be part of the password.
	Exclude string
	// Group of characters used to generate the pool.
	Levels []Level
	// Password length.
	Length uint64
	// Character repetition.
	Repeat bool
	// contains filtered or unexported fields
}

Password represents a sequence of characters required for access to a computer system.

Example
package main

import (
	"fmt"
	"log"

	"github.com/GGP1/atoll"
)

func main() {
	p := &atoll.Password{
		Length:  22,
		Levels:  []atoll.Level{atoll.Lower, atoll.Upper, atoll.Special},
		Include: "1+=g ",
		Exclude: "&r/ty",
		Repeat:  false,
	}

	password, err := atoll.NewSecret(p)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(password)
	// Example output:
	// AE8f@,1^P_Ws=c!ho`T{Á+
}
Output:

func (*Password) Entropy

func (p *Password) Entropy() float64

Entropy returns the password entropy in bits.

func (*Password) Generate

func (p *Password) Generate() ([]byte, error)

Generate generates a random password.

type Secret added in v0.2.0

type Secret interface {
	Generate() ([]byte, error)
	Entropy() float64
}

Secret is the interface that wraps the basic methods Generate and Entropy.

Jump to

Keyboard shortcuts

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