4.1 【必须】不得明文存储用户密码等敏感数据
用户密码应该使用 Argon2, scrypt, bcrypt, pbkdf2 等算法做哈希之后再存入存储系统, https://password-hashing.net/
用户敏感数据,应该做到传输过程中加密,存储状态下加密 传输过程中加密,可以使用 HTTPS 等认证加密通信协议
存储状态下加密,可以使用 SQLCipher 等类似方案。
4.2 【必须】内存中的用户密码等敏感数据应该安全抹除
例如用户密码等,即使是临时使用,也应在使用完成后应当将内容彻底清空。
错误:
正确:
...
string user_password(100, '\0');
...
OPENSSL_cleanse(&user_password[0], user_password.size());
}
关联漏洞:
高风险-敏感信息泄露
4.3 【必须】rand() 类函数应正确初始化
上述代码执行完成后,foo的值是固定的。它等效于 srand(1); rand();
。
// Good
srand(time(0));
int foo = rand();
}
关联漏洞:
高风险-逻辑漏洞
4.4 【必须】在需要高强度安全加密时不应使用弱PRNG函数
在需要生成 AES/SM1/HMAC 等算法的密钥/IV/Nonce, RSA/ECDSA/ECDH 等算法的私钥,这类需要高安全性的业务场景,必须使用密码学安全的随机数生成器 (Cryptographically Secure PseudoRandom Number Generator (CSPRNG) ), 不得使用 rand()
等无密码学安全性保证的普通随机数生成器。
推荐使用的 CSPRNG 有:
OpenSSL 中的
RAND_bytes()
函数, https://www.openssl.org/docs/man1.1.1/man3/RAND_bytes.htmllibsodium 中的
randombytes_buf()
函数Linux kernel 的
getrandom()
系统调用, . 或者读 /dev/urandom 文件, 或者 /dev/random 文件。Apple IOS 的
SecRandomCopyBytes()
, https://developer.apple.com/documentation/security/1399291-secrandomcopybytesWindows 下的 ,
CryptGenRandom()
,RtlGenRandom()
例如 C 标准库中的 rand()
的实现只是简单的,生成的伪随机数具有较强的可预测性。
当需要实现高强度加密,例如涉及通信安全时,不应当使用 rand()
作为随机数发生器。
实际应用中, C++11 标准提供的random_device
保证加密的安全性和随机性
但是 。跨平台的代码可以考虑用 OpenSSL 等保证密码学安全的库里的随机数发生器。
关联漏洞:
高风险-敏感数据泄露
4.5 【必须】自己实现的rand范围不应过小
如果在弱安全场景相关的算法中自己实现了PRNG,请确保rand出来的随机数不会很小或可预测。
// Bad
int32_t val = ((state[0] * 1103515245U) + 12345U) & 999999;
上述例子可能想生成0~999999共100万种可能的随机数,但是999999的二进制是11110100001000111111,与&运算后,0位一直是0,所以生成出的范围明显会小于100万种。
关联漏洞:
高风险-逻辑漏洞