我想知道是否可以在我的数据库中保存加密文本字段,并且能够根据salt和授权密码解密这段文本?
例如:
$Salt = $_POST['Salt'];
$Password = $Query_Results['Password'];
if ($salt == $Stored_Salt AND $Authorized_Password == $Password){
//Perform a decryption of the stored results
echo $Decrypted_TextField;
}
我正在创建一个完全加密/编码的数据库。除了标识符的整数字段之外,什么都不是纯文本。其他所有内容都将被加密/编码。许多人将使用单向加密,但有些字段需要容纳双向加密类型。
我无法在数据库中存放未加密的文本。在存储之前,所有东西都需要加密。但对我来说这是一个未知的过程。所以我想知道我是否可以从哪里开始获得一些帮助
答案 0 :(得分:8)
听起来你可能想要更多关于加密的背景知识,特别是DB加密选项(你没有提到数据存储,但是有完全加密的MySQL和Postgres选项)。一般来说,“滚动你自己”几乎总是一个坏主意,不幸的是,在mcrypt()和openssl _ *()函数之间,坦率地向新手提供了太多选项(例如将EBC和CBC呈现为同等有效选项)。虽然这个帖子:https://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own主要是谈论创建“新颖的”加密原语是徒劳的,但这个原则也适用于实现应用程序和数据库级加密的天真尝试。
实际上,您可能需要处理的最具挑战性的事情是密码/密钥管理问题。下面的代码将所有责任都放在客户端(发件人)上 - 除非您保存提交的密码(这种方式违背了整个目的),如果用户忘记或以后无法提供密码,加密数据在数据库中将不可恢复。 (并且,是的,如果您真的想要沿着牦牛剃须路径走下去,那么可以选择多键信封加密)。
如果您存储密钥/密码服务器端,那么您最多只会在对手的路径上放置一个小路障:如果她能够设法读取您的密钥文件,她就可以检索数据。但最糟糕的是,通过在本地保存密码,您会给用户一种虚假的安全感,如果这是财务,健康或其他受保护的信息,您和您的组织就会承担这种责任的负担。
最后,这里有一个成熟的库:http://phpseclib.sourceforge.net/crypt/examples.html但在我看来,它为新手用户提供了太多选项(例如,参见代码生成器中的默认EBC模式)。对于密码散列,请在此处仔细查看phpPass库:http://www.openwall.com/phpass/。
所有这一切,这是一个简单的双向,相当强的加密,随机生成的初始化向量和盐,以及256位AES对称(例如,非公钥)密码的工作开始。测试OSX Lion& CentOS / RedHat 6。
祝你好运!//$message = escapeshellarg( $_POST['message'] );
$message = 'This is my very secret data SSN# 009-68-1234';
// Set to some reasonable limit for DB.
// Make sure to size DB column +60 chars
$max_msg_size = 1000;
$message = substr($message, 0, $max_msg_size);
// User's password (swap for actual form post)
//$password = escapeshellarg( $_POST['password'] );
$password = 'opensesame';
// Salt to add entropy to users' supplied passwords
// Make sure to add complexity/length requirements to users passwords!
// Note: This does not need to be kept secret
$salt = sha1(mt_rand());
// Initialization Vector, randomly generated and saved each time
// Note: This does not need to be kept secret
$iv = substr(sha1(mt_rand()), 0, 16);
echo "\n Password: $password \n Message: $message \n Salt: $salt \n IV: $iv\n";
$encrypted = openssl_encrypt(
"$message", 'aes-256-cbc', "$salt:$password", null, $iv
);
$msg_bundle = "$salt:$iv:$encrypted";
echo " Encrypted bundle = $msg_bundle \n\n ";
// Save it... (make sure to use bind variables/prepared statements!)
/* db_write( "insert into sensitive_table encrypted_msg values (:msg_bundle)",
$msg_bundle ); */
现在检索它:
// Retrieve from DB...
//$password = escapeshellarg( $_POST['password'] );
$password = 'opensesame';
// Swap with actual db retrieval code here
//$saved_bundle = db_read( "select encrypted_msg from sensitive_table" );
$saved_bundle = $msg_bundle;
// Parse iv and encrypted string segments
$components = explode( ':', $saved_bundle );;
var_dump($components);
$salt = $components[0];
$iv = $components[1];
$encrypted_msg = $components[2];
$decrypted_msg = openssl_decrypt(
"$encrypted_msg", 'aes-256-cbc', "$salt:$password", null, $iv
);
if ( $decrypted_msg === false ) {
die("Unable to decrypt message! (check password) \n");
}
$msg = substr( $decrypted_msg, 41 );
echo "\n Decrypted message: $decrypted_msg \n";
示例输出:
Password: opensesame
Message: This is my very secret data SSN# 009-68-1234
Salt: 3f12ce187d5c5bcc3b0d5acf1e76fad8b684ff37
IV: 00c1d3b4c6a6f4c3
Encrypted bundle = 3f12ce187d5c5bcc3b0d5acf1e76fad8b684ff37:00c1d3b4c6a6f4c3:KB6k+GlM+0EHbETUgEe8Lck0nF5qBz+51wc5LtmS4XMOm0Pfyyr2PIXMVEyzs/41
array(3) {
[0]=>
string(40) "3f12ce187d5c5bcc3b0d5acf1e76fad8b684ff37"
[1]=>
string(16) "00c1d3b4c6a6f4c3"
[2]=>
string(64) "KB6k+GlM+0EHbETUgEe8Lck0nF5qBz+51wc5LtmS4XMOm0Pfyyr2PIXMVEyzs/41"
}
Decrypted message: This is my very secret data SSN# 009-68-1234
答案 1 :(得分:2)
不是一个完整的答案,而是扩大了腌制的工作时间太长而无法发表评论......
不应将salt视为要比较的字符串,它应该是最终用户不必键入的密码的一部分,但对于该用户是唯一的。它用于防止单个受损密码破坏多个帐户。
例如,假设我们有一个非常简单的系统,Bob有密码ABCDEF
。
通过我们的哈希算法传递ABCDEF
会产生(比方说)ED6522687
如果攻击者可以访问密码列表,他们只能看到存储的哈希值。
当然,如果Jane也使用相同的密码,她的哈希也将是ED6522687
- 这意味着如果你闯入任何一个帐户(通过蛮力,社会工程等),你将会去访问两个帐户,因为您可以看到他们的哈希匹配。
Salting是在散列之前对密码执行的操作,对每个用户而言是唯一的且可重复的。盐应该是可预测的,所以让我们说鲍勃和简的盐是随机数。
现在,如果您对bob ABCDEF123
的密码进行哈希处理,则会获得与Jane ABCDEF456
不同的哈希值。
请注意,此不是完整说明。还需要考虑其他一些事项:
bcrypt
这样的哈希算法设计成计算成本很高。不像(例如)SHA2
另一个通常不够强调的观察......你永远不应该相信你在互联网上读到的关于这样一个话题的任何事情 - 有太多人不完全理解(我认为自己就是其中之一)。因此,不要自己这样做,而不是如何做到这一点的指南。