所以这对我来说有点棘手,就像标题中所说的那样,我正在尝试制作该程序,因此当您尝试输入数据库中已经存在的电子邮件时,它会给您一个错误,听起来很简单,但我有尝试了至少一次文档,当我尝试它时,它只是不返回任何内容,并且仍然将电子邮件注册为数据库中的新帐户,甚至没有错误消息(我检查过),所以一定是真的出了问题。我不知道我还能怎么做。我以前从未做过密码学,我真的不知道自己在做什么。
如果您还有任何可以帮助我变得更好的提示或文档,我将不胜感激。
我所有的代码都是 PHP 的 我使用的密码方法是 AES-128-GCM
有人可能会说在某些函数中用 cypher 代替了 cipher,只是我更改了一些变量名称以使其在英语中更容易理解,有些可能已经滑倒了。
这是在 register.php 中的表单之后
if (isset($_POST['register_user'])){
$hashed_password = password_hash($_POST["password"], PASSWORD_DEFAULT);
//cipher the data
$cipher_name = cipherData($_POST["name"]);
$cipher_lastname = cipherData($_POST["lastname"]);
$cipher_email = cipherData($_POST["email"]);
//function to compare the input email with the ones in the DB
$email_checked=$db->checkEmail($_POST["email"]);
if($email_checked == true){
echo"The email is already registered";
}else{
if(isset($_POST['is_admin'])){
$db->registerUser($cipher_name ,$cipher_lastname ,$cipher_email ,1,$hashed_password);
}else{
$db->registerUser($cipher_name ,$cipher_lastname ,$cipher_email ,0,$hashed_password);
}
}*/
header('register.php');
}
这里是checkEmail函数,这个函数在connection.php里面
public function checkEmail($email_input) {
$users= $this->resultQueryToJSON(
"SELECT user_id
FROM t_user",
['user_id']
);
foreach($users as $row_user){
$get_emails= $this->resultQueryToJSON(
"SELECT user_email
FROM t_user
WHERE user_id = '".$row_user['user_id']."'",
['user_email']
);
$email = $get_emails[0]['user_email'];
//I decipher the email so i can compare them
$email_guardado= decipherData($email);
if ($email_guardado == $email_input){
return true;
}
}
}
这是 decipherData 函数
function decipherData($cipher_data){
global $cipher;
global $tag;
global $key;
if (in_array($cipher, openssl_get_cipher_methods())){
//this was set up in the cipherData function
list($cipher_data, $iv) = explode('::', base64_decode($cipher_data), 2);
$decipher_data= openssl_decrypt($cipher_data, $cipher, $key, $options=0, $iv, $tag);
return $decipher_data;
}
}
只是因为我讨厌这里的帖子中没有解释的函数是 cipherData 函数,以防它有助于澄清我在做什么
function cipherData($data){
global $cipher;
global $tag;
global $key;
if (in_array($cipher, openssl_get_cipher_methods())&& isset($data)){
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
$cipher_data= openssl_encrypt($data, $cipher, $key, $options=0, $iv, $tag);
return base64_encode($cipher_data . '::' . $iv);
}else{
echo'Cipher Error';
}
}
谢谢大家
所以我几乎明白了,我想我知道问题出在哪里,但我不知道它到底是什么,问题出在 decipher() 函数中,我认为这是因为我试图从 foreach 访问它,但我不确定。这是我目前的代码
public function checkEmail($email_input) {
$list_emails= $this->resultQueryToJSON(
"SELECT user_email
FROM t_user",
['user_email']
);
foreach($list_emails as $emails){
$email = implode(" ",$emails);
$saved_email= decipherData($email)
return $saved_email;
}
}
如
aes-128-gcm
文档中
openssl_encrypt()
的示例所述,您需要将返回的值存储在 $tag
中。
我对加密一无所知,所以我不知道这是否可以接受,但你可以将它添加到你的base64编码数据中:
function decipherData($cipher_data) {
global $cipher;
global $key;
if (in_array($cipher, openssl_get_cipher_methods())){
//this was set up in the cipherData function
list($cipher_data, $iv, $tag) = explode('::', base64_decode($cipher_data), 3);
$decipher_data= openssl_decrypt($cipher_data, $cipher, $key, $options=0, $iv, $tag);
return $decipher_data;
}
}
function cipherData($data) {
global $cipher;
global $key;
if (in_array($cipher, openssl_get_cipher_methods()) && isset($data)){
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
$cipher_data = openssl_encrypt($data, $cipher, $key, $options=0, $iv, $tag);
return base64_encode($cipher_data . '::' . $iv . '::' . $tag);
} else {
echo 'Cipher Error';
}
}
正如其他人在评论中指出的那样,迭代所有电子邮件地址并解密它们以查看它们是否与输入电子邮件匹配是非常低效的。对于少数用户来说还好,但对于数以万计的用户来说就不太好了。