假设我想在0到27之间生成一个安全的随机int,使用:
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error)
Run Code Online (Sandbox Code Playgroud)
在"crypto/rand"
包中.
我该怎么办?
我真的不明白它是如何工作的,为什么它不会返回内置的Go ints而不是指向某个big.Int类型的指针?
编辑:
这对于令牌来说是否足够安全?
func getToken(length int) string {
token := ""
codeAlphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
codeAlphabet += "abcdefghijklmnopqrstuvwxyz"
codeAlphabet += "0123456789"
for i := 0; i < length; i++ {
token += string(codeAlphabet[cryptoRandSecure(int64(len(codeAlphabet)))])
}
return token
}
func cryptoRandSecure(max int64) int64 {
nBig, err := rand.Int(rand.Reader, big.NewInt(max))
if err != nil {
log.Println(err)
}
return nBig.Int64()
}
func main() {
fmt.Println(getToken(32))
}
Run Code Online (Sandbox Code Playgroud)
这将输出如下内容:
qZDbuPwNQGrgVmZCU9A7FUWbp8eIfn0Z
EwZVoQ5D5SEfdhiRsDfH6dU6tAovILCZ
cOqzODVP0GwbiNBwtmqLA78rFgV9d3VT
Run Code Online (Sandbox Code Playgroud)
eli*_*rar 22
如果您正在为会话ID,OAuth承载令牌,CSRF或类似物生成安全令牌:您希望生成(理想情况下)256位(32字节)或不小于192位(24字节)的令牌.
值在(0-27)之间的标记可以在不到一秒的时间内强制强制,并且不能被认为是安全的.
例如
package main
import (
"crypto/rand"
"encoding/base64"
)
// GenerateRandomBytes returns securely generated random bytes.
// It will return an error if the system's secure random
// number generator fails to function correctly, in which
// case the caller should not continue.
func GenerateRandomBytes(n int) ([]byte, error) {
b := make([]byte, n)
_, err := rand.Read(b)
// Note that err == nil only if we read len(b) bytes.
if err != nil {
return nil, err
}
return b, nil
}
// GenerateRandomString returns a URL-safe, base64 encoded
// securely generated random string.
func GenerateRandomString(s int) (string, error) {
b, err := GenerateRandomBytes(s)
return base64.URLEncoding.EncodeToString(b), err
}
func main() {
// Example: this will give us a 44 byte, base64 encoded output
token, err := GenerateRandomString(32)
if err != nil {
// Serve an appropriately vague error to the
// user, but log the details internally.
}
}
Run Code Online (Sandbox Code Playgroud)
base64输出对于标头,HTTP表单,JSON主体等是安全的.
如果你需要一个整数,它可能有助于解释你的用例,因为系统要求令牌作为整数是奇怪的.
Hec*_*orJ 20
这是一些工作代码:
package main
import (
"fmt"
"crypto/rand"
"math/big"
)
func main() {
nBig, err := rand.Int(rand.Reader, big.NewInt(27))
if err != nil {
panic(err)
}
n := nBig.Int64()
fmt.Printf("Here is a random %T in [0,27) : %d\n", n, n)
}
Run Code Online (Sandbox Code Playgroud)
但要生成随机令牌,我会做这样的事情:
package main
import (
"crypto/rand"
"encoding/base32"
"fmt"
)
func main() {
token := getToken(10)
fmt.Println("Here is a random token : ", token)
}
func getToken(length int) string {
randomBytes := make([]byte, 32)
_, err := rand.Read(randomBytes)
if err != nil {
panic(err)
}
return base32.StdEncoding.EncodeToString(randomBytes)[:length]
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
19153 次 |
最近记录: |