Skip to content

sergeymakinen/go-crypt

Repository files navigation

crypt

tests Go Reference Go Report Card codecov

Package crypt implements a basic interface to validate crypt(3) hashes.

Validation of any particular hash requires the prior registration of a check function. Registration is typically automatic as a side effect of initializing that hash's package so that, to validate an Argon2 has, it suffices to have

import _ "github.com/sergeymakinen/go-crypt/argon2"

in a program's main package. The _ means to import a package purely for its initialization side effects.

Supported hashing algorithms

Name Package Supported parameters Example hash
Argon2 argon2 Go Reference
  • Salt
  • Memory
  • Time
  • Threads
  • Prefix ($argon2d$, $argon2i$, $argon2id$)
  • Version (1.0, 1.3)
$argon2id$v=19$m=512,t=3,p=1$qXMlAYBABLl$/OuG+qcZ1ntdTRfhUGFVp2YMcTPJ7aH3e4j7KIEnRho
bcrypt bcrypt Go Reference
  • Salt
  • Cost
  • Prefix ($2$, $2a$, $2b$)
$2b$10$UVjcf7m8L91VOpIRwEprguF4o9Inqj7aNhqvSzUElX4GWGyIkYLuG
DES des Go Reference
  • Salt
eNBO0nZMf3rWM
DES Extended (BSDi) desext Go Reference
  • Salt
  • Rounds
_6C/.yaiu.qYIjNR7X.s
MD5 md5 Go Reference
  • Salt
$1$ip0xp41O$7DHwMihQRmDjn2tiJ17mw.
NT Hash nthash Go Reference $3$$8846f7eaee8fb117ad06bdd830b7586c
SHA-1 sha1 Go Reference
  • Salt
  • Rounds
$sha1$48000$mHh0IIOQ$YS/Lw0PKCThSEBBYqP37zXySQ3cC
SHA-256 sha256 Go Reference
  • Salt
  • Rounds
$5$rounds=505000$.HnFpd3anFzRwVj5$EdcK/Q9wfmq1XsG5OTKP0Ns.ZlN9DRHslblcgCLtXY5
SHA-512 sha512 Go Reference
  • Salt
  • Rounds
$6$rounds=505000$69oRpYjidkp7hFdm$nbf4615NgTuG8kCnGYSjz/lXw4KrGMVR16cbCa9CSIHXK8UXwCK9bzCqDUw/I8hgb9Wstd1w5Bwgu5YG6Q.dm.
Sun MD5 sunmd5 Go Reference
  • Salt
  • Rounds
  • Prefix ($md5,, $md5$)
  • Whether to add an empty value to a salt
$md5,rounds=5000$ReCRHeOH$$WOV3YlBRWykkmQDJc.uia/

Custom hashes

It's also possible to implement a custom hash marshaling/unmarshaling via the hash package.

Supported schemes:

  • DES: <value>(<value>)*
  • DES Extended (BSDi): _<value>(<value>)*
  • MCF/PHC: $<id>$fragment($<fragment>)*
    Where:
    • <fragment> is (<group>|<param>=<value>|<value>)
    • <group> is <param>=<value>,<param>=<value>(,<param>=<value>)*

Example:

var scheme = struct {
    HashPrefix string
    Cost       string `hash:"length:2"`
    Salt       []byte   `hash:"length:22,inline"`
    Sum        [31]byte
}
hash.Unmarshal("$2b$10$UVjcf7m8L91VOpIRwEprguF4o9Inqj7aNhqvSzUElX4GWGyIkYLuG", &scheme)

Installation

Use go get:

go get github.com/sergeymakinen/go-crypt

Then import the package into your own code:

import "github.com/sergeymakinen/go-crypt"

Example

package main

import (
	"fmt"

	"github.com/sergeymakinen/go-crypt"
	_ "github.com/sergeymakinen/go-crypt/argon2"
	_ "github.com/sergeymakinen/go-crypt/bcrypt"
)

var hashes = []string{
	"$argon2id$v=19$m=512,t=3,p=1$qXMlAYBABLl$/OuG+qcZ1ntdTRfhUGFVp2YMcTPJ7aH3e4j7KIEnRho", // Argon2
	"$2b$12$mBhJFLLDJCBCcmMN4DLyrOV.LLSl/mdwGfzwsqvIL0OQN5yXzRihO",                         // bcrypt
	"$unknown$foo", // Not registered
}

var passwords = []string{
	"password",
	"test",
}

func main() {
	for _, hash := range hashes {
		for _, password := range passwords {
			fmt.Printf("%q with %q: %v\n", hash, password, crypt.Check(hash, password))
		}
	}
	// Output:
	// "$argon2id$v=19$m=512,t=3,p=1$qXMlAYBABLl$/OuG+qcZ1ntdTRfhUGFVp2YMcTPJ7aH3e4j7KIEnRho" with "password": <nil>
	// "$argon2id$v=19$m=512,t=3,p=1$qXMlAYBABLl$/OuG+qcZ1ntdTRfhUGFVp2YMcTPJ7aH3e4j7KIEnRho" with "test": hash and password mismatch
	// "$2b$12$mBhJFLLDJCBCcmMN4DLyrOV.LLSl/mdwGfzwsqvIL0OQN5yXzRihO" with "password": <nil>
	// "$2b$12$mBhJFLLDJCBCcmMN4DLyrOV.LLSl/mdwGfzwsqvIL0OQN5yXzRihO" with "test": hash and password mismatch
	// "$unknown$foo" with "password": unknown hash
	// "$unknown$foo" with "test": unknown hash
}

License

BSD 3-Clause