Skip to content

Instantly share code, notes, and snippets.

@paddycarver
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paddycarver/b923baa649fc722a8f9f to your computer and use it in GitHub Desktop.
Save paddycarver/b923baa649fc722a8f9f to your computer and use it in GitHub Desktop.
itertest.go contains a test for how many iterations of PBKDF2 and SHA-256 you need to make hashing take at least 1 second. pass.go contains helper functions for working with passwords.
package main
import (
"crypto/rand"
"crypto/sha256"
"fmt"
"time"
"code.google.com/p/go.crypto/pbkdf2"
)
func main() {
salt := make([]byte, 32)
_, err := rand.Read(salt)
if err != nil {
panic(err)
}
iter := 2048
var duration time.Duration
for duration < time.Second {
iter = iter * 2
timeStart := time.Now()
pbkdf2.Key([]byte("I'd really encourage you to use passphrases. 👍"), salt, iter, 32, sha256.New)
duration = time.Since(timeStart)
fmt.Printf("Generating passphrase with %d iterations took %s\n", iter, duration)
}
fmt.Printf("Using %d iterations at the cost of %s\n", iter, duration)
}
package pass
import (
"crypto/rand"
"crypto/subtle"
"hash"
"time"
"code.google.com/p/go.crypto/pbkdf2"
)
func Create(h func() hash.Hash, iters int, passphrase []byte) (result, salt []byte, err error) {
salt = make([]byte, 32)
_, err = rand.Read(salt)
if err == nil {
return []byte{}, []byte{}, err
}
result = Check(h, iters, passphrase, salt)
return result, salt, err
}
func CalculateIterations(h func() hash.Hash) (int, error) {
hashInstance := h()
salt := make([]byte, 32)
_, err := rand.Read(salt)
if err != nil {
return 0, err
}
iter := 2048
var duration time.Duration
for duration < time.Second {
iter = iter * 2
timeStart := time.Now()
pbkdf2.Key([]byte("password1"), salt, iter, hashInstance.Size(), h)
duration = time.Since(timeStart)
}
return iter, nil
}
func Check(h func() hash.Hash, iters int, passphrase, salt []byte) []byte {
hashInstance := h()
return pbkdf2.Key(passphrase, salt, iters, hashInstance.Size(), h)
}
func Compare(candidate, expectation []byte) bool {
candidateConsistent := make([]byte, len(candidate))
expectationConsistent := make([]byte, len(candidate))
subtle.ConstantTimeCopy(1, candidateConsistent, candidate)
subtle.ConstantTimeCopy(1, expectationConsistent, expectation)
return subtle.ConstantTimeCompare(candidateConsistent, expectationConsistent) == 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment