我在下面写了一些代码,可以创建帐户。我想通过加密所有数据(密码和用户名除外)来添加额外的保护层。我有两个问题:
1。 Openssl是最好的php加密实践吗?
2。如何在我的代码中添加openssl?
在将openssl与准备好的语句代码集成时,我有些困难。
我的代码:
<?php
session_start();
require_once './config/config.php';
require_once 'includes/auth_validate.php';
//Only super admin is allowed to access this page
if ($_SESSION['admin_type'] !== 'super') {
// show permission denied message
echo 'Permission Denied';
exit();
}
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$admin_type = mysqli_real_escape_string($conn, $_POST['admin_type']);
$position = mysqli_real_escape_string($conn, $_POST['position']);
$first_name = mysqli_real_escape_string($conn, $_POST['first_name']);
$last_name = mysqli_real_escape_string($conn, $_POST['last_name']);
$user_name = mysqli_real_escape_string($conn, $_POST['user_name']);
$email = mysqli_real_escape_string($conn, $_POST['email']);
$phone_number = mysqli_real_escape_string($conn, $_POST['phone_number']);
$passwd = mysqli_real_escape_string($conn, $_POST['passwd']);
$about = mysqli_real_escape_string($conn, $_POST['about']);
//Error handlers
//Check for empty fields
if (empty($admin_type) || empty($position) || empty($first_name) || empty($last_name) || empty($user_name) || empty($passwd)){
$_SESSION['failure'] = "Admin was not created, missing imporant details!";
header('location: admin_users');
exit();
} else {
$sql = "SELECT * FROM admin_accounts WHERE user_name='$user_name'";
$result = mysqli_query($conn, $sql);
$resultCheck = mysqli_num_rows($result);
if ($resultCheck > 0) {
$_SESSION['failure'] = "Admin was not created, username already used!";
header('location: admin_users');
exit();
} else {
//Hashing password
$hashedPasswd = password_hash($passwd, PASSWORD_DEFAULT);
//Insert the user into the database
$sql = "INSERT INTO admin_accounts (admin_type, position, first_name, last_name, user_name, email, phone_number, passwd, about) VALUES (?,?,?,?,?,?,?,?,?);";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo "SQL Error";
} else {
mysqli_stmt_bind_param($stmt, "sssssssss", $admin_type, $position, $first_name, $last_name, $user_name, $email, $phone_number, $hashedPasswd, $about);
mysqli_stmt_execute($stmt);
{
$_SESSION['success'] = "Admin user added successfully!";
header('location: admin_users');
exit();
}
}
}
}
}
$edit = false;
Openssl_Encryption示例:
<?php
//$key should have been previously generated in a cryptographically safe way, like openssl_random_pseudo_bytes
$plaintext = "message to be encrypted";
$cipher = "aes-128-gcm";
if (in_array($cipher, openssl_get_cipher_methods()))
{
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext = openssl_encrypt($plaintext, $cipher, $key, $options=0, $iv, $tag);
//store $cipher, $iv, and $tag for decryption later
$original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, $options=0, $iv, $tag);
echo $original_plaintext."\n";
}
我仅尝试加密名字:(这不起作用,在数据库中无效)
<?php
session_start();
require_once './config/config.php';
require_once 'includes/auth_validate.php';
//ONLY SUPER ADMINS ARE ALLOWED TO ACCESS THIS PAGE
if ($_SESSION['admin_type'] !== 'super') {
// show permission denied message
echo 'Permission Denied';
exit();
}
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$admin_type = mysqli_real_escape_string($conn, $_POST['admin_type']);
$position = mysqli_real_escape_string($conn, $_POST['position']);
$first_name = mysqli_real_escape_string($conn, $_POST['first_name']);
$last_name = mysqli_real_escape_string($conn, $_POST['last_name']);
$user_name = mysqli_real_escape_string($conn, $_POST['user_name']);
$email = mysqli_real_escape_string($conn, $_POST['email']);
$phone_number = mysqli_real_escape_string($conn, $_POST['phone_number']);
$passwd = mysqli_real_escape_string($conn, $_POST['passwd']);
$about = mysqli_real_escape_string($conn, $_POST['about']);
//EROOR HANDLERS
//CHECK FOR EMPTY FIELDS
if (empty($admin_type) || empty($position) || empty($first_name) || empty($last_name) || empty($user_name) || empty($passwd)){
$_SESSION['failure'] = "Admin was not created, missing imporant details!";
header('location: admin_users');
exit();
} else {
$sql = "SELECT * FROM admin_accounts WHERE user_name='$user_name'";
$result = mysqli_query($conn, $sql);
$resultCheck = mysqli_num_rows($result);
if ($resultCheck > 0) {
$_SESSION['failure'] = "Admin was not created, username already used!";
header('location: admin_users');
exit();
} else {
//HASHING PASSWORD
$hashedPasswd = password_hash($passwd, PASSWORD_DEFAULT);
//INSERT THE USER INTO THE DATABASE
$sql = "INSERT INTO admin_accounts (admin_type, position, first_name, last_name, user_name, email, phone_number, passwd, about) VALUES (?,?,?,?,?,?,?,?,?);";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo "SQL Error";
} else {
mysqli_stmt_bind_param($stmt, "sssssssss", $admin_type, $position, $first_name, $last_name, $user_name, $email, $phone_number, $hashedPasswd, $about);
mysqli_stmt_execute($stmt);
{
$first_name = mysqli_real_escape_string($conn, $_POST['first_name']);
$cipher = "aes-128-gcm";
if (in_array($cipher, openssl_get_cipher_methods()))
{
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext = openssl_encrypt($first_name, $cipher, $key, $options=0, $iv, $tag);
}
}
{
$_SESSION['success'] = "Admin user added successfully!";
header('location: admin_users');
exit();
}
}
}
}
}
$edit = false;
?>
答案 0 :(得分:1)
。我想通过加密所有数据来添加额外的保护层 (密码和用户名除外)。
正如我在评论中提到的那样,实用方面是您可能无法搜索使用AES加密的任何数据,这是因为每次加密某项时AES都会返回不同的值。这是一件好事,但几乎不可能进行搜索。除了AES之外,还可以使用SHA256之类的方法创建哈希,哈希可以每次返回相同的值(但是这是一种方法,没有解密)。因此,通过将散列存储在数据库中,您可以对数据进行散列并在先前存储的数据库中查找散列。这样做的缺点是,除了增加复杂性之外,还通常会削弱您的加密。如果他们不能攻击AES,则可以尝试强行使用HASH。
现在说,如果您真的需要加密一些数据。然后,我在用户表中创建一个字段,然后对数据进行JSON编码或序列化。这将基本上将数据数组转换为字符串。然后,您可以加密该字符串。
您将无法搜索数据,但是所有数据都将集中在一个位置,并且只需解密一次即可。
$data = ['foo'=>'bar', 'stuff'=>'otherthing'];
$json = json_encode($data); //'{"foo":"bar", "stuff":"otherthing"}'
$encrypted = AESencrypt($json); //or whatever the function is
然后您将$encrypted
保存在一个名为secure或类似内容的字段中。
最后一件事,我强烈建议使用PHPSecLib2.0
https://github.com/phpseclib/phpseclib
它不仅会为您提供一个更好的API,因为它是面向对象的,而且还具有SSL的本机植入(尽管安装open_ssl扩展会使其更快)。
使用PHPseclib,这就是您要做的一切
function encryptAES($key, $plaintext){
$Cipher = new AES(AES::MODE_CBC);
$Cipher->setKey($key);
//create the IV
$iv = Random::string($Cipher->getBlockLength() >> 3);
$Cipher->setIV($iv);
//encrypt and combine (you have to know the IV to decode. this is the typical way it's done) the IV is like a salt.
$encrypted = $iv_base64 . base64_encode($Cipher->encrypt($plaintext));
return $encrypted;
}
function decryptAES($key, $plaintext){
$Cipher = new AES(AES::MODE_CBC);
$Cipher->setKey($key);
//find and decode the iv
$iv = base64_decode(substr($ciphertext, 0, 22) . '==');
//remove the iv from ciphertext
$encrypted = substr($ciphertext, 22);
$Cipher->setIV($iv);
$decrypted = $Cipher->decrypt(base64_decode($encrypted));
return $decrypted;
}
您必须对其进行base64编码,因为它是二进制的,因此它将存储在文本字段中。您也许可以在数据库中使用某种类型的二进制字段。多数时候,我进行加密时都是在处理文件,所以我不确定。
注意
请注意,任何对称2向加密(使用1个密钥而不是公共/私有对的加密)都适用。是它的安全性仅与加密密钥一样安全。因为服务器必须知道该KEY,所以如果有人要访问文件系统和服务器的DB,那么他们很有可能能够找到用于加密的密钥。这严重限制了它提供的“真实”安全性。这并不是说不值得做,只是您在处理需要加密的数据时必须了解局限性并意识到风险。例如,我不会在服务器上使用AES来存储信用卡或其他PCI类型的数据。
基本上,它将安全性职责从数据库转移到了代码所在的服务器。原始数据是无用的,因为它已加密,但是代码必须可以访问KEY,如果有人可以访问,则他们同样可以解密数据。您可以采取一些措施来增强服务器的抵抗攻击能力(DMZ等),但这超出了此处的讨论范围。
干杯。