CodeQL 文档

将随机性不足的值用作加密算法的密钥

ID: go/insecure-randomness
Kind: path-problem
Security severity: 7.8
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-338
Query suites:
   - go-code-scanning.qls
   - go-security-extended.qls
   - go-security-and-quality.qls

单击以在 CodeQL 代码库中查看查询

使用加密强度较弱的伪随机数生成器来生成安全敏感值(例如密码)会使攻击者更容易预测该值。

伪随机数生成器生成的数字序列仅近似于随机数的属性。该序列并非真正的随机序列,因为它完全由一组相对较小的初始值(种子)决定。如果随机数生成器的加密强度较弱,则可以通过外部观察轻松预测该序列。

建议

如果输出将用于安全敏感的上下文中,请使用加密安全的伪随机数生成器。根据经验,如果预测某个值将允许攻击者执行他们原本无法执行的操作,则该值应被视为“安全敏感的”。例如,如果攻击者可以预测为新用户生成的随机密码,则他们将能够以该新用户的身份登录。

对于 Go,crypto/rand 提供了加密安全的伪随机数生成器。math/rand 的加密安全性较低,应避免在安全上下文中使用。对于非安全敏感的上下文,math/rand 可能是更好的选择,因为它具有更方便的接口,并且可能更快。

示例

以下示例使用 math/rand 包而不是 crypto/rand 来生成密码

package main

import (
	"math/rand"
)

var charset = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")

func generatePassword() string {
	s := make([]rune, 20)
	for i := range s {
		s[i] = charset[rand.Intn(len(charset))]
	}
	return string(s)
}

而应使用 crypto/rand

package main

import (
	"crypto/rand"
	"math/big"
)

func generatePasswordGood() string {
	s := make([]rune, 20)
	for i := range s {
		idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
		if err != nil {
			// handle err
		}
		s[i] = charset[idx.Int64()]
	}
	return string(s)
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私