diff --git a/command/crypto/jwk/create.go b/command/crypto/jwk/create.go index 25a463a1..e17f1532 100644 --- a/command/crypto/jwk/create.go +++ b/command/crypto/jwk/create.go @@ -562,7 +562,7 @@ func createAction(ctx *cli.Context) error { return errors.Wrap(err, "error reading password") } - salt, err := randutil.GetRandomSalt(pbkdf2SaltSize) + salt, err := randutil.Salt(pbkdf2SaltSize) if err != nil { return err } @@ -574,7 +574,7 @@ func createAction(ctx *cli.Context) error { P2S: salt, } } else { - key, err := randutil.RandAlphanumeric(32) + key, err := randutil.Alphanumeric(32) if err != nil { return errors.Wrap(err, "error generating password") } diff --git a/command/crypto/jwt/sign.go b/command/crypto/jwt/sign.go index a1d196cc..d36a3aca 100644 --- a/command/crypto/jwt/sign.go +++ b/command/crypto/jwt/sign.go @@ -283,7 +283,7 @@ func signAction(ctx *cli.Context) error { c.IssuedAt = jose.NewNumericDate(now) } if c.ID == "" && ctx.IsSet("jti") { - if c.ID, err = randutil.RandHex(40); err != nil { + if c.ID, err = randutil.Hex(40); err != nil { return errors.Wrap(err, "error creating random jti") } } diff --git a/command/oauth/cmd.go b/command/oauth/cmd.go index 5f094f44..9452c128 100644 --- a/command/oauth/cmd.go +++ b/command/oauth/cmd.go @@ -282,12 +282,12 @@ type oauth struct { } func newOauth(provider, clientID, clientSecret, authzEp, tokenEp, scope, loginHint string) (*oauth, error) { - state, err := randutil.GenerateRandomRestrictedString(32) + state, err := randutil.Alphanumeric(32) if err != nil { return nil, err } - challenge, err := randutil.GenerateRandomRestrictedString(64) + challenge, err := randutil.Alphanumeric(64) if err != nil { return nil, err } diff --git a/crypto/randutil/random.go b/crypto/randutil/random.go index 2587d4f0..a8fa58f4 100644 --- a/crypto/randutil/random.go +++ b/crypto/randutil/random.go @@ -8,8 +8,19 @@ import ( "github.com/pkg/errors" ) -// GetRandomSalt generates a new salt of the given size. -func GetRandomSalt(size int) ([]byte, error) { +var ascii string + +func init() { + // initialize the charcters in ascii + aciiBytes := make([]byte, 94) + for i := range aciiBytes { + aciiBytes[i] = byte(i + 33) + } + ascii = string(aciiBytes) +} + +// Salt generates a new random salt of the given size. +func Salt(size int) ([]byte, error) { salt := make([]byte, size) _, err := io.ReadFull(rand.Reader, salt) if err != nil { @@ -18,10 +29,10 @@ func GetRandomSalt(size int) ([]byte, error) { return salt, nil } -// RandString returns a random string of a given length using the characters -// in the given string. It splits the string on runes to support UTF-8 +// String returns a random string of a given length using the characters in +// the given string. It splits the string on runes to support UTF-8 // characters. -func RandString(length int, chars string) (string, error) { +func String(length int, chars string) (string, error) { result := make([]rune, length) runes := []rune(chars) for i := range result { @@ -34,54 +45,22 @@ func RandString(length int, chars string) (string, error) { return string(result), nil } -// RandHex returns a random string of the given length using the hexadecimal +// Hex returns a random string of the given length using the hexadecimal // characters in lower case (0-9+a-f). -func RandHex(length int) (string, error) { - return RandString(length, "0123456789abcdef") +func Hex(length int) (string, error) { + return String(length, "0123456789abcdef") } -// RandAlphanumeric returns a random string of the given length using the 62 +// Alphanumeric returns a random string of the given length using the 62 // alphanumeric characters in the POSIX/C locale (a-z+A-Z+0-9). -func RandAlphanumeric(length int) (string, error) { - return RandString(length, "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") +func Alphanumeric(length int) (string, error) { + return String(length, "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") } -// GenerateRandomASCIIString returns a securely generated random ASCII string. -// It reads random numbers from crypto/rand and searches for printable characters. -// It will return an error if the system's secure random number generator fails to +// Ascii returns a securely generated random ASCII string. It reads random +// numbers from crypto/rand and searches for printable characters. It will +// return an error if the system's secure random number generator fails to // function correctly, in which case the caller must not continue. -func GenerateRandomASCIIString(length int) (string, error) { - result := "" - for { - if len(result) >= length { - return result, nil - } - num, err := rand.Int(rand.Reader, big.NewInt(int64(127))) - if err != nil { - return "", err - } - n := num.Int64() - // Make sure that the number/byte/letter is inside - // the range of printable ASCII characters (excluding space and DEL) - if n > 32 && n < 127 { - result += string(n) - } - } -} - -// GenerateRandomRestrictedString returns a securely generated random ASCII string. -// It reads random numbers from crypto/rand and searches for printable characters. -// It will return an error if the system's secure random number generator fails to -// function correctly, in which case the caller must not continue. -func GenerateRandomRestrictedString(length int) (string, error) { - const chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - result := make([]byte, length) - for i := range result { - num, err := rand.Int(rand.Reader, big.NewInt(int64(len(chars)))) - if err != nil { - return "", err - } - result[i] = chars[num.Int64()] - } - return string(result), nil +func Ascii(length int) (string, error) { + return String(length, ascii) } diff --git a/jose/generate.go b/jose/generate.go index 17aa6cdb..c0b44e84 100644 --- a/jose/generate.go +++ b/jose/generate.go @@ -160,7 +160,7 @@ func generateOctKey(size int, alg, use, kid string) (*JSONWebKey, error) { size = DefaultOctSize } - key, err := randutil.RandAlphanumeric(size) + key, err := randutil.Alphanumeric(size) if err != nil { return nil, err } diff --git a/utils/reader/read.go b/utils/reader/read.go index 3178dadd..ef952056 100644 --- a/utils/reader/read.go +++ b/utils/reader/read.go @@ -68,7 +68,7 @@ func GeneratePasswordOnEmpty(ptr *string, key string) error { if len(*ptr) == 0 { var err error - if *ptr, err = randutil.GenerateRandomRestrictedString(passwordLength); err != nil { + if *ptr, err = randutil.Alphanumeric(passwordLength); err != nil { return errors.Wrapf(err, "Failed to generate %s", key) } fmt.Printf("\n\n%s: %s\n\n", key, *ptr)