diff options
| author | ebiggers <ebiggers@google.com> | 2020-01-22 19:16:20 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-22 19:16:20 -0800 |
| commit | 303616dc52e2b1e71883417a291f07c59025215d (patch) | |
| tree | 7cbace927ccef0392706fff52d1a56cb906f52ee /crypto/rand.go | |
| parent | 059482129c5fdafebc582887a4ae4ef80988b708 (diff) | |
| parent | 8cd1b3ba2e7a12cd68e2dfd0cbb5ec09ff92783b (diff) | |
Merge pull request #167 from ebiggers/recovery-passphrase
Automatically generate recovery passphrase when useful
Diffstat (limited to 'crypto/rand.go')
| -rw-r--r-- | crypto/rand.go | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/crypto/rand.go b/crypto/rand.go index 736d969..4d8c044 100644 --- a/crypto/rand.go +++ b/crypto/rand.go @@ -49,6 +49,38 @@ func NewRandomKey(length int) (*Key, error) { return NewFixedLengthKeyFromReader(randReader{}, length) } +// NewRandomPassphrase creates a random passphrase of the specified length +// containing random alphabetic characters. +func NewRandomPassphrase(length int) (*Key, error) { + chars := []byte("abcdefghijklmnopqrstuvwxyz") + passphrase, err := NewBlankKey(length) + if err != nil { + return nil, err + } + for i := 0; i < length; { + // Get some random bytes. + raw, err := NewRandomKey((length - i) * 2) + if err != nil { + return nil, err + } + // Translate the random bytes into random characters. + for _, b := range raw.data { + if int(b) >= 256-(256%len(chars)) { + // Avoid bias towards the first characters in the list. + continue + } + c := chars[int(b)%len(chars)] + passphrase.data[i] = c + i++ + if i == length { + break + } + } + raw.Wipe() + } + return passphrase, nil +} + // randReader just calls into Getrandom, so no internal data is needed. type randReader struct{} |