1
0
Fork 0
forked from forgejo/forgejo

Use base32 for 2FA scratch token (#18384)

* Use base32 for 2FA scratch token
* rename Secure* to Crypto*, add comments
This commit is contained in:
wxiaoguang 2022-01-26 12:10:10 +08:00 committed by GitHub
parent 4889ab52de
commit 49dd906753
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 41 additions and 37 deletions

View file

@ -137,8 +137,8 @@ func MergeInto(dict map[string]interface{}, values ...interface{}) (map[string]i
return dict, nil
}
// RandomInt returns a random integer between 0 and limit, inclusive
func RandomInt(limit int64) (int64, error) {
// CryptoRandomInt returns a crypto random integer between 0 and limit, inclusive
func CryptoRandomInt(limit int64) (int64, error) {
rInt, err := rand.Int(rand.Reader, big.NewInt(limit))
if err != nil {
return 0, err
@ -146,27 +146,27 @@ func RandomInt(limit int64) (int64, error) {
return rInt.Int64(), nil
}
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
const alphanumericalChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
// RandomString generates a random alphanumerical string
func RandomString(length int64) (string, error) {
bytes := make([]byte, length)
limit := int64(len(letters))
for i := range bytes {
num, err := RandomInt(limit)
// CryptoRandomString generates a crypto random alphanumerical string, each byte is generated by [0,61] range
func CryptoRandomString(length int64) (string, error) {
buf := make([]byte, length)
limit := int64(len(alphanumericalChars))
for i := range buf {
num, err := CryptoRandomInt(limit)
if err != nil {
return "", err
}
bytes[i] = letters[num]
buf[i] = alphanumericalChars[num]
}
return string(bytes), nil
return string(buf), nil
}
// RandomBytes generates `length` bytes
// This differs from RandomString, as RandomString is limits each byte to have
// a maximum value of 63 instead of 255(max byte size)
func RandomBytes(length int64) ([]byte, error) {
bytes := make([]byte, length)
_, err := rand.Read(bytes)
return bytes, err
// CryptoRandomBytes generates `length` crypto bytes
// This differs from CryptoRandomString, as each byte in CryptoRandomString is generated by [0,61] range
// This function generates totally random bytes, each byte is generated by [0,255] range
func CryptoRandomBytes(length int64) ([]byte, error) {
buf := make([]byte, length)
_, err := rand.Read(buf)
return buf, err
}

View file

@ -120,20 +120,20 @@ func Test_NormalizeEOL(t *testing.T) {
}
func Test_RandomInt(t *testing.T) {
int, err := RandomInt(255)
int, err := CryptoRandomInt(255)
assert.True(t, int >= 0)
assert.True(t, int <= 255)
assert.NoError(t, err)
}
func Test_RandomString(t *testing.T) {
str1, err := RandomString(32)
str1, err := CryptoRandomString(32)
assert.NoError(t, err)
matches, err := regexp.MatchString(`^[a-zA-Z0-9]{32}$`, str1)
assert.NoError(t, err)
assert.True(t, matches)
str2, err := RandomString(32)
str2, err := CryptoRandomString(32)
assert.NoError(t, err)
matches, err = regexp.MatchString(`^[a-zA-Z0-9]{32}$`, str1)
assert.NoError(t, err)
@ -141,13 +141,13 @@ func Test_RandomString(t *testing.T) {
assert.NotEqual(t, str1, str2)
str3, err := RandomString(256)
str3, err := CryptoRandomString(256)
assert.NoError(t, err)
matches, err = regexp.MatchString(`^[a-zA-Z0-9]{256}$`, str3)
assert.NoError(t, err)
assert.True(t, matches)
str4, err := RandomString(256)
str4, err := CryptoRandomString(256)
assert.NoError(t, err)
matches, err = regexp.MatchString(`^[a-zA-Z0-9]{256}$`, str4)
assert.NoError(t, err)
@ -157,18 +157,18 @@ func Test_RandomString(t *testing.T) {
}
func Test_RandomBytes(t *testing.T) {
bytes1, err := RandomBytes(32)
bytes1, err := CryptoRandomBytes(32)
assert.NoError(t, err)
bytes2, err := RandomBytes(32)
bytes2, err := CryptoRandomBytes(32)
assert.NoError(t, err)
assert.NotEqual(t, bytes1, bytes2)
bytes3, err := RandomBytes(256)
bytes3, err := CryptoRandomBytes(256)
assert.NoError(t, err)
bytes4, err := RandomBytes(256)
bytes4, err := CryptoRandomBytes(256)
assert.NoError(t, err)
assert.NotEqual(t, bytes3, bytes4)