Last active
August 29, 2015 14:04
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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