Ponieważ to pytanie dotyczy bezpieczeństwa.
Nie używaj biblioteki mysql_*. Jest szalenie podatny na wstrzykiwanie sql, zwłaszcza w jaki sposób go używasz. I jest przestarzały.
Załóżmy, że przekazuję [email protected]
W Twoim kodzie
$domain = $emailsep[1]; // will equal "gmail.com"
Teraz powiedzmy, że wstrzykuję go za pomocą wstrzyknięcia sql, ponieważ przekazując [email protected]
jest raczej nudne, prawda?
Będę się dobrze bawić w następującym wierszu kodu:
$domaincheck = mysql_query("SELECT * FROM xxxxxxx WHERE domain = '$domain'", $link);
I używaj mysqli lub pdo zgodnie z zaleceniami tych lekarzy.
Edytuj:
teraz wróć do pytania, które miałeś na myśli
jeden plik php
<?php
date_default_timezone_set('America/New_York'); // required something here else exception below
//error_reporting(E_ALL);
//ini_set("display_errors", 1);
//require '1error_2shutdown_3log.php'; // 1. err hndlr, 2. shutdown hndlr, 3. log it somehow
$b='<br/n>'; // great name huh ?
$b2='<br/n><br/n>'; // great name huh ?
echo "The time is " . date("h:i:sa").$b;
echo "s01".$b;
try {
echo "s02".$b."--------------------------------------------------------------------------".$b;
//$email = $_POST['emailreg'];
//$firstna = $_POST['firstna'];
//$surna = $_POST['surna'];
//$password = $_POST['passreg'];
//$passconfirm = $_POST['passconfirm'];
//$userpass = $email . $password;
//$emailsep = explode("@", $email);
//$domain = $emailsep[1];
$email = "[email protected]";
$firstna = "Drew";
$surna = "Pierce";
$password = "secure";
$passconfirm = "secure";
$userpass = $email . $password;
$emailsep = explode("@", $email);
$domain = $emailsep[1];
$key = md5('united'); // don't use md5
$salt = md5('united'); // don't use md5
function encrypt($string, $key) {
$b='<br/n>'; // great name huh ?
$b2='<br/n><br/n>'; // great name huh ?
# come up with a good key, beyond the scope of this Question
$key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3"); #32 bytes
$key_size = strlen($key);
echo "Key size: " . $key_size . $b; # 32, big surprise
# create a random IV to use with CBC encoding
# yes each time
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); // using ECB cuz u were
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
echo "in encrypt() passed <b>",$string,"</b> and <b>",$key.'</b>'.$b;
$rawEncrypted=mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $string, MCRYPT_MODE_ECB,$iv);
# prepend the IV for it to be available for decryption
$rawEncrypted = $iv . $rawEncrypted;
$b64Encrypted= base64_encode($rawEncrypted); # <------- RIGHT HERE WE ARE DONE
# basically we are done encrypting, could just return $b64Encrypted and be done with it
# but no
#########################################################################
# lifted from manual page btw: http://php.net/manual/en/function.mcrypt-encrypt.php
# do an assert that you can decrypt for a sanity check
$ciphertext_dec = base64_decode($b64Encrypted);
# retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
$iv_dec = substr($ciphertext_dec, 0, $iv_size);
# retrieves the cipher text (everything except the $iv_size in the front)
$ciphertext_dec = substr($ciphertext_dec, $iv_size);
# may remove 00h valued characters from end of plain text
$plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $ciphertext_dec, MCRYPT_MODE_ECB, $iv_dec);
echo "Assert ... plaintext= ".$plaintext_dec .$b;
// a real Assert would make it explode, but you get the idea
#########################################################################
echo "leaving encrypt() with ",$b64Encrypted.$b2;
return $b64Encrypted;
}
echo "about to connect ...".$b;
$link = mysql_connect('localhost', 'GuySmiley', 'mongoose');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("so_gibberish", $link);
$domaincheck = mysql_query("SELECT * FROM t1 WHERE domain = '$domain'", $link);
if($domaincheck === FALSE) {
die(mysql_error());
}
//echo "encrypt returns: ".encrypt($email, $key).$b;
$emailcheck = mysql_query("SELECT * FROM t2 WHERE studentemail = '".encrypt($email, $key)."'", $link);
if($emailcheck === FALSE) {
die(mysql_error());
}
$dorow = mysql_fetch_array($domaincheck);
$emailrow = mysql_fetch_array($emailcheck);
// the below will explode, I don't have them, changed to echo
if ($password == '') {
$cause = 'Password Blank'; echo 'error.php'.$b;
}elseif ($passconfirm =='') {
$cause = 'Password Blank'; echo 'error.php'.$b;
}elseif ($password != $passconfirm) {
$cause = 'Password Mismatch'; echo 'error.php'.$b;
}elseif ($dorow['domain'] != $domain) {
$cause = 'Incorrect Domain'; echo 'error.php'.$b;
}elseif ($emailrow['studentemail'] != '') {
$cause = 'User Already Exists'; echo 'error.php'.$b;
}
//elseif ($dorow['licensecount'] > $dorow['licensemax']) { # commented out cuz I dont have this table
//$cause = 'Insufficient Licences'; echo 'error.php'.$b;
//}else {
//}
function hashword($string, $salt){
$b='<br/n>'; // great name huh ?
echo "in hashword()".$b;
$string = crypt($string, '$1$' . $salt . '$');
return $string;
}
echo "s10".$b;
$userpass = hashword($userpass, $salt);
echo "s11".$b;
echo $userpass.$b;
$hash = md5( rand(0,1000) ); // don't use md5, get a good RNG (random # generator)
echo "s12".$b;
$sql="INSERT INTO `xxxxxxx`.`xxxxxxx`
(`hash`, `studentemail`, `studentfirstname`, `studentsurname`,
`oscopetutcount`, `siggentutcount`, `mmetertutcount`, `lprobetutcount`,
`psupplytutcount`, `oscopetest`, `siggentest`, `mmetertest`, `lprobetest`,
`psupplytest`, `exam`, `userpass`, `ID`, `domain`, `licensecount`,
`licensemax`, `licenceexpire`)
VALUES ('$hash', '".encrypt($email, $key)."', '".encrypt($firstna, $key)."',
'".encrypt($surna, $key)."', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '$userpass', NULL, '', '0', '', NULL)";
echo $sql.$b;
//$result = mysql_query($sql, $link);
//$licenceadd = mysql_query("UPDATE xxxxxxx.xxxxxxx SET licensecount = licensecount +1 WHERE domain = '$domain'", $link);
//if($result === FALSE) {
// die(mysql_error());
//}
//if($licenceadd === FALSE) {
// die(mysql_error());
//}
//include 'email.php';
echo "near bottom".$b;
mysql_close($link);
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), $b;
} finally {
echo $b."--------------------------------------------------------------------------".$b."First finally".$b;
}
?>
Schemat, który był aktywny, kiedy to uruchomiłem
create table t1
( id int auto_increment primary key,
domain varchar(100) not null,
key(domain)
);
insert t1(domain) values ('gmail.com'),('yahoo.com'),('ibm.com');
-- drop table t2;
create table t2
( id int auto_increment primary key,
fullName varchar(80) not null,
studentemail varchar(1000) not null
-- key(studentemail)
);
-- truncate table t2;
insert t2(fullName,studentemail) values ('Drew Pierce','who-knows');
Wyjście na ekranie:
The time is 06:25:20pm
s01
s02
--------------------------------------------------------------------------
about to connect ...
*** begin myLogger function ***
lvl: 8192 | msg:mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead | file:C:\Apache24\htdocs\causes_parse_error.php | ln:82
warn
*** end myLogger function ***
Key size: 32
in encrypt() passed [email protected] and ��K~:صGc��U��)���^A~/�*�
Assert ... plaintext= [email protected]
leaving encrypt() with 7n7aTyDo4E4WvtDseUcSM3JMjKipFalVRWhPwu6P5vUdYjN9btNNPo1qlOxB+TKtwfCCr/2ctTCNPxrdVz5Egg==
error.php
s10
in hashword()
s11
$1$3db1a73a$i5Pb3o2s6tV4uWDivvmLA1
s12
Key size: 32
in encrypt() passed [email protected] and ��K~:صGc��U��)���^A~/�*�
Assert ... plaintext= [email protected]
leaving encrypt() with uXCKvAUVuBcoPxIbqpbfMZRD50Bu7XSwP75MapBct9UdYjN9btNNPo1qlOxB+TKtwfCCr/2ctTCNPxrdVz5Egg==
Key size: 32
in encrypt() passed Drew and ��K~:صGc��U��)���^A~/�*�
Assert ... plaintext= Drew
leaving encrypt() with 61B1AJtpaK7hx0bFSBNXr9Z0ZFIUkrQXCZcQ5D4pvySzLFfIEEB/2r2FvCLZMobUd3jWRIiyFSfLy4/qTXsT5w==
Key size: 32
in encrypt() passed Pierce and ��K~:صGc��U��)���^A~/�*�
Assert ... plaintext= Pierce
leaving encrypt() with /JFBohEe96R7sFnQxu+ujvgFv8WZl9Pdss+zv8tVptJk2xrZH8Pb3xjfGmWGH92W/h4aeWrPS8ICEIojKtYrgw==
INSERT INTO `xxxxxxx`.`xxxxxxx` (`hash`, `studentemail`, `studentfirstname`, `studentsurname`, `oscopetutcount`, `siggentutcount`, `mmetertutcount`, `lprobetutcount`, `psupplytutcount`, `oscopetest`, `siggentest`, `mmetertest`, `lprobetest`, `psupplytest`, `exam`, `userpass`, `ID`, `domain`, `licensecount`, `licensemax`, `licenceexpire`) VALUES ('a96b65a721e561e1e3de768ac819ffbb', 'uXCKvAUVuBcoPxIbqpbfMZRD50Bu7XSwP75MapBct9UdYjN9btNNPo1qlOxB+TKtwfCCr/2ctTCNPxrdVz5Egg==', '61B1AJtpaK7hx0bFSBNXr9Z0ZFIUkrQXCZcQ5D4pvySzLFfIEEB/2r2FvCLZMobUd3jWRIiyFSfLy4/qTXsT5w==', '/JFBohEe96R7sFnQxu+ujvgFv8WZl9Pdss+zv8tVptJk2xrZH8Pb3xjfGmWGH92W/h4aeWrPS8ICEIojKtYrgw==', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '$1$3db1a73a$i5Pb3o2s6tV4uWDivvmLA1', NULL, '', '0', '', NULL)
near bottom
--------------------------------------------------------------------------
First finally
Zasadniczo jestem zadowolony ze sposobu, w jaki wychodzą ASSERTS, z osadzonymi IV (wektorami inicjalizacji).
Zapisywanie do bazy danych nie było problem z tym pytaniem, ponieważ możesz zobaczyć skomentowany ten obszar. Raczej było to pytanie o szyfrowanie/odszyfrowywanie.
Odbiorca zaszyfrowanego tekstu może go odszyfrować jako przedrostek IV i będzie miał klucz. Jeśli nie mają klucza, szkoda.
Powodzenia ! I zmień tę bibliotekę na ... jak ... PDO !