taracybersec / php-security
PHP Security - 一个现代且安全的PHP库,提供了一系列加密数据、解密数据、生成安全随机密码、清理数据等方法。它使用PHP内置的加密功能构建,设计简单易用且安全性高。
Requires
- php: >=7.2
README
简介
PHP Security是一个现代且安全的PHP库,提供了一系列加密数据、解密数据、生成安全随机密码等方法。它使用PHP内置的加密功能构建,设计简单易用且安全性高。
特性
- 使用多种算法(AES-256-CBC、AES-128-GCM、ChaCha20-Poly1305等)安全加密和解密数据
- 支持基于密码和密钥加密/解密
- 生成具有各种特性(长度、大小写、数字、符号)的复杂且安全随机密码
要求
- PHP 7.2或更高版本
安装
使用以下命令安装最新版本
composer require taracybersec/php-security
加密特性
1. 设置密钥
要设置用于加密和解密数据的密钥,可以使用以下方法。该方法接受一个字符串作为参数,并设置所有加密和解密方法使用的密钥。密钥用于对称加密和解密。建议在应用程序启动时设置密钥一次,并保存在安全的位置。
use TaraCyberSec\PhpSecurity\Crypto;
Crypto::setSecretKey('your_secret_key');
2. 生成密钥
要生成用于加密和解密数据的密钥,可以使用以下方法。该方法生成一个随机密钥,可用于使用指定的算法(AES-256-CBC等)加密和解密数据。该方法返回一个可存储在数据库或通过网络发送的编码字符串。密钥用于对称加密和解密。建议在应用程序启动时生成一个新的密钥一次,并保存在安全的位置。生成的密钥是加密安全的,适用于高安全应用程序。
use TaraCyberSec\PhpSecurity\Crypto;
Crypto::generateSecretKey(Crypto::ALGO_AES_256_CBC);
3. 加密数据
要使用密钥加密数据,可以使用以下方法。该方法使用AES-256-CBC算法(您可以选择自己的)和密钥加密数据。该方法返回一个base64编码的字符串,可以存储在数据库中或通过网络发送。
use TaraCyberSec\PhpSecurity\Crypto;
$data = "Sensitive information";
Crypto::setSecretKey('your_secret_key');
$encryptedData = Crypto::encrypt($data, Crypto::ALGO_AES_256_CBC);
4. 解密数据
要解密使用密钥加密的数据,可以使用以下方法。该方法使用指定的算法(AES-256-CBC等)和密钥解密数据。该方法返回一个解密字符串,可以被您的应用程序使用。解密过程使用setSecretKey方法设置的密钥。
use TaraCyberSec\PhpSecurity\Crypto;
$data = "your encrypted data";
Crypto::setSecretKey('your_secret_key');
$encryptedData = Crypto::decrypt($data, Crypto::ALGO_AES_256_CBC);
5. 检查算法是否受支持
要检查加密算法是否受当前PHP版本支持,可以使用以下方法。该方法检查指定的算法是否受当前PHP版本支持,如果不支持,则返回false。如果算法受支持,则返回true。此方法在您想在加密数据之前检查算法是否受支持时很有用。
use TaraCyberSec\PhpSecurity\Crypto;
echo Crypto::isAlgorithmSupported('algo_name');
6. 获取支持的算法
要获取当前PHP版本支持的加密算法列表,可以使用以下方法。此方法返回当前PHP版本支持的算法列表,在使用它加密数据之前检查算法是否支持是一种很好的方法。
支持的加密算法数量可能因PHP版本、操作系统和硬件而异。但是,支持的算法列表是稳定的,除非PHP有重大版本发布,否则不会改变。
use TaraCyberSec\PhpSecurity\Crypto;
$supportedEncAlgos = Crypto::getSupportedAlgorithms();
7. 生成随机字符串
要生成安全的随机字符串,请使用此方法。它将返回指定长度的随机字符串。如果您需要生成用于生成盐、生成令牌或其他任何需要随机字符串的场景,此方法非常有用。随机字符串中的字符数将是指定的长度。该方法将返回一个字符串。
use TaraCyberSec\PhpSecurity\Crypto;
echo Crypto::generateRandomString(32);
8. 生成安全的随机密码
要生成具有指定特征的随机密码,请使用此方法。它将返回一个指定长度的随机密码,至少包含一个小写字母、一个大写字母、一个数字和一个符号。该方法将返回一个字符串。
use TaraCyberSec\PhpSecurity\Crypto;
echo Crypto::generateSecureRandomPassword(24, Crypto::PASS_LOWERCASE_ON, Crypto::PASS_UPPERCASE_ON, Crypto::PASS_NUMBERS_ON, Crypto::PASS_SYMBOLS_ON);
9. 为CryptoJS加密数据
要为CryptoJS加密数据,请使用此方法。它使用支持JavaScript中CryptoJS库的指定算法加密数据。它返回一个JSON编码的字符串,可以安全地传递给JavaScript中使用的CryptoJS库。加密数据将兼容CryptoJS库,这是一个流行的JavaScript库,用于加密和解密数据。加密数据是JSON编码的,因此可以轻松地作为字符串传递到JavaScript中。加密数据将以包含加密数据的data属性和包含加密时使用的初始化向量的iv属性的JSON对象返回。加密数据的字符数将根据加密数据的长度而变化。该方法将返回一个字符串。
use TaraCyberSec\PhpSecurity\Crypto;
$data = "Sensitive information";
Crypto::setSecretKey('your_secret_key');
echo Crypto::encryptForCryptoJS($data, Crypto::ALGO_AES_256_CBC);
10. 从CryptoJS解密数据
要从CryptoJS解密数据,请使用此方法。它使用支持JavaScript中CryptoJS库的指定算法解密数据。它返回一个字符串,该字符串是使用JavaScript中CryptoJS库加密的。解密数据的字符数将与加密数据的字符数相同。该方法将返回一个字符串。
use TaraCyberSec\PhpSecurity\Crypto;
$data = "your encrypted data";
Crypto::setSecretKey('your_secret_key');
$encryptedData = Crypto::decryptFromCryptoJS($data, Crypto::ALGO_AES_256_CBC);
注意:为了确保在使用CryptoJS时加密数据具有兼容的格式,请按照以下步骤操作
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
const encrypt = (text, key) => {
try {
return CryptoJS.AES.encrypt(JSON.stringify(text), key, {
format: {
"encrypt": function (value, password) {
if (password.match(/[^\x00-\x7F]/)) {
console.warn("CryptoJSAES: Your passphrase contains non ASCII characters - This is not supported. Hash your passphrase with MD5 or similar hashes to prevent those issues");
}
return CryptoJS.AES.encrypt(JSON.stringify(value), password, { "format": CryptoJSAesJson }).toString();
},
"decrypt": function (jsonStr, password) {
if (password.match(/[^\x00-\x7F]/)) {
console.warn("CryptoJSAES: Your passphrase contains non ASCII characters - This is not supported. Hash your passphrase with MD5 or similar hashes to prevent those issues");
}
return JSON.parse(CryptoJS.AES.decrypt(jsonStr, password, { "format": CryptoJSAesJson }).toString(CryptoJS.enc.Utf8));
},
"stringify": function (cipherParams) {
var j = { "ct": cipherParams.ciphertext.toString(CryptoJS.enc.Base64) };
if (cipherParams.iv) j.iv = cipherParams.iv.toString();
if (cipherParams.salt) j.s = cipherParams.salt.toString();
return JSON.stringify(j).replace(/\s/g, "");
},
"parse": function (jsonStr) {
var j = JSON.parse(jsonStr);
var cipherParams = CryptoJS.lib.CipherParams.create({ "ciphertext": CryptoJS.enc.Base64.parse(j.ct) });
if (j.iv) cipherParams.iv = CryptoJS.enc.Hex.parse(j.iv);
if (j.s) cipherParams.salt = CryptoJS.enc.Hex.parse(j.s);
return cipherParams;
}
}
}).toString();
} catch (error) {
console.log(error.stack);
return false;
}
}
Sanitize中的功能
1. 深度编码
为了安全地清理数据数组以防止XSS攻击,您可以使用deepEncode方法。此方法通过递归编码数组的每个元素来深度编码数据数组。它确保即使攻击者成功将恶意数据注入到数组元素中,它也将被HTML编码,并且不会被浏览器作为代码执行。编码数据的元素数量将与原始数据的元素数量相同。该方法将返回一个编码数据的数组。
use TaraCyberSec\PhpSecurity\Sanitize;
$data = $request->all();
$data = Sanitize::deepEncode($data);
$request->replace($data);
2. 编码
要编码输入字符串,您可以使用encode方法。它通过HTML编码输入字符串以防止XSS攻击。这意味着字符串中的任何特殊HTML字符,如"<"和">",将被其相应的HTML实体替换,如"<"和">",使其在HTML文档中使用时安全。编码字符串中的字符数将正好与原始字符串中的字符数相同。该方法将返回一个字符串。
use TaraCyberSec\PhpSecurity\Sanitize;
$data = "<script>alert("some data")</script> here is a script";
$data = Sanitize::encode($data);
3. 深度清理
为了清理数据数组,您可以使用deepClean方法。此方法通过递归地清理数组中的每个元素,无论其类型如何,来清理数组中的每个元素。这样,即使攻击者成功将恶意数据注入到数组中的某个元素,这些数据也会被清理,不会由浏览器作为代码执行。此外,它还会修剪字符串并从其中删除标签,使数据在您的应用程序中使用时更安全。清理后的数据中的元素数量将与原始数据中的元素数量相同。该方法将返回一个清理后的数据数组。
use TaraCyberSec\PhpSecurity\Sanitize;
$data = $request->all();
$data = Sanitize::deepClean($data);
$request->replace($data);
4. 清理
要清理输入字符串,您可以使用clean方法。它通过trim从字符串的两端删除空白字符,并使用strip_tags从字符串中删除标签,从而移除字符串中的HTML实体。这样,即使攻击者成功将恶意数据注入到字符串中,这些数据也会被修剪,且不带标签,使其无害。
use TaraCyberSec\PhpSecurity\Sanitize;
$data = "<script>alert("some data")</script> here is a script";
$data = Sanitize::clean($data);
5. 验证上传的文件
要验证上传的文件,您可以使用validateUploadedFiles方法。它通过扫描文件内容以查找恶意代码或文件来验证上传的文件,确保它们可以安全地上传到您的Web服务器。它递归地扫描请求体中的每个文件,并检查文件内容是否可以安全上传。此方法有助于防止文件上传攻击和代码注入攻击。它执行以下检查:
- 根据文件的MIME类型检查文件是否是有效的图像、PDF或电子表格文件。
- 扫描文件内容以查找常见的恶意模式。
- 根据文件扩展名检查文件是否是有效的文件类型。
如果任何这些检查失败,方法将错误消息添加到错误数组中。然后,方法返回错误数组。如果错误数组为空,则表示请求体中的所有文件都可以安全上传。
use TaraCyberSec\PhpSecurity\Sanitize;
$errors = Sanitize::validateUploadedFiles();
if (!empty($errors)) {
http_response_code(422);
header('Content-Type: application/json');
echo json_encode([
'message' => $errors[0],
'errors' => $errors
]);
die;
}
服务器功能
1. 添加安全头
要向所有响应添加安全头,您可以使用addSecurityHeaders方法。通过设置Content-Security-Policy、X-Content-Type-Options、X-Frame-Options、X-XSS-Protection、Referrer-Policy、Strict-Transport-Security和Feature-Policy头,它有助于防止XSS攻击、点击劫持和其他安全威胁。
use TaraCyberSec\PhpSecurity\Server;
Server::addSecurityHeaders();
2. 设置速率限制存储路径
可选
要设置速率限制存储路径,您可以使用setRateLimitStoragePath方法。此方法设置库将存储速率限制数据的位置。该方法接受一个字符串作为参数,并将路径设置为指定的目录。该目录必须存在且可以被Web服务器写入。默认路径是当前工作目录。
use TaraCyberSec\PhpSecurity\Server;
$path = __DIR__ . "/rate_limit";
Server::setRateLimitStoragePath($path);
3. 强制执行速率限制
要强制执行速率限制,此方法检查请求是否在指定的速率限制内。如果请求在速率限制内,它返回true。如果请求超出速率限制,它停止脚本执行并返回一个带有429状态码的JSON响应。此方法接受两个参数:在指定间隔内允许的最大请求数量,以及间隔秒数。
use TaraCyberSec\PhpSecurity\Server;
Server::enforceRateLimiting();
您可以通过以下方式自定义速率限制默认值
use TaraCyberSec\PhpSecurity\Server;
$requestLimit = 200; // max requests allowed in the interval: like 200 requests per 30 seconds
$interval = 30; // in seconds
Server::enforceRateLimiting($requestLimit, $interval);