我将敏感信息以'text'字段格式存储在mysql数据库中,该格式使用openssl_public加密加密,并使用openssl_private_decrypt进行解密。
然而,我面临的问题是,当我尝试使用我的php脚本来“解码”文本时,返回的值中有几个撇号和引号,因此无法进行解密。任何想法如何解决这个问题?
注意:我最初尝试将我的信息存储在字段类型'varbinary'中,但每次都解密失败。
在审查了一些之后,我想也许php和mysql很难处理所有信息(~800条记录),因为有时候字段是空白的,其他字段不是。如果我逐个存储,它可以解决零问题,但是当尝试运行foreach循环时,它几乎总是会导致错误。有任何想法吗?要编码的脚本如下:
<?php
$publickey = file_get_contents("certificate.pem");
function encrypt($text)
{
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));
}
try {
$db = new PDO('mysql:host=localhost;dbname=DBNAME', 'USER', 'PW');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->beginTransaction();
$start = microtime(true);
$stmt = $db->prepare("SELECT ID, ITEM1_old, ITEM2_old FROM tablename");
$stmt->execute();
$rows = $stmt->fetchAll();
foreach($rows as $row) {
$id = $row['0'];
$item1 = $row['1'];
$item2 = $row['2'];
define('SALT', $id);
$item1_enc = encrypt($item1);
$item2_enc = encrypt($item2);
openssl_public_encrypt($item1_enc, $item1_ssl_enc, $publickey);
openssl_public_encrypt($item2_enc, $item2_ssl_enc, $publickey);
$stmt2 = $db->prepare("UPDATE tablename SET ITEM1_new=?, ITEM2_new=? WHERE ID=?");
$stmt2->execute(array($item1_ssl_enc, $item2_ssl_enc, $id));
}
$db->commit();
$db->NULL;
$elapsed = microtime(true) - $start;
echo "Finished.<br />Elapsed time: ".$elapsed;
}
catch (PDOException $e)
{
$db->rollback();
echo "There was a system error.".$e->getMessage();
}
?>
答案 0 :(得分:1)
问题是密码在块中加密,如果纯文本与密码的块大小不匹配,它将被填充。这是正常和正确的,您需要在加密之前将长度字段打包到数据中。
$plaintext = 'text to encrypt';
$plaintext = pack('V', strlen($plaintext)) . $plaintext;
$ciphertext = encrypt($plaintext);
然后返回输出:
$plaintext = decrypt($ciphertext);
$header = unpack('Vsize', $plaintext);
$plaintext = substr($plaintext, 4, $header['size'] + 4);
此外,如果您的有效负载超过一百字节或更少,您不应使用RSA加密整个有效负载,您应该生成随机密钥,使用密钥加密有效负载,然后加密密钥与您的公共/私钥。 RSA不是为加密大型有效载荷而设计的,它旨在共享一个秘密来初始化一个更快的对称密码,如Blowfish。
例如
/* Generate the random key */
$key = '';
for($i = 0; $i < 255; ++$i)
$key .= chr(mt_rand(0, 255));
$key = sha1($key);
/* Pack & encrypt the payload with the key */
$plaintext = pack('V', strlen($plaintext)) . $plaintext;
$ciphertext = encrypt($plaintext, $key);
/* Encrypt the key with the public key */
$key = public_encrypt($key);
$payload = pack('V', strlen($key)) . $key . $ciphertext;
解密