2013-06-06 4 views
6

キー塩に基づいて文字列を復号化?例えば暗号化/私は私のデータベース内で暗号化されたテキストフィールドを保持することが可能であった場合には不思議と塩と許可パスワードに基づいてテキストのこの部分を復号化する機能を備えていた

$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

対称暗号化アルゴリズムを調べるAES – Patashu

+0

@Patashu php.netのAES関数の解読に関するドキュメント:http://www.php.net/manual/en/function.mcrypt-decrypt.phpは文書化されていませんこれらの機能を実際に実装する方法について説明します。あなたが成功した暗号化機能を提供すれば、光を放つことができますか? –

+0

対称暗号化機能とAESがどのように機能するかの文献を読んでください。その関数のすべてのパラメータが明らかになります。 – Patashu

答えて

7
あなたは一般的に暗号上のいくつかのより多くの背景をしたいかもしれないようですね

、および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ライオン& 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 
2

ない完全な答えが、コメントのために長すぎた作品を塩漬け方法の拡大を..

塩は、塩として扱われるべきではありませんパスワードは、エンドユーザーが入力する必要はなく、そのユーザーに固有のパスワードの一部でなければなりません。単一の侵害されたパスワードが複数のアカウントに違反しないようにするために使用されます。

たとえば、パスワードがABCDEFの本当にシンプルなシステムがあるとしましょう。攻撃者がパスワードリストへのアクセス権を取得した場合

ED6522687

(例えば)で、当社のハッシュアルゴリズムの結果を通じてABCDEFを渡すと、彼らは唯一の保存されたハッシュを見ることができます。

もちろん、Janeも同じパスワードを使用すると、ハッシュ値はED6522687になります。つまり、いずれかのアカウントに侵入した場合(ブルートフォース、ソーシャルエンジニアリングなど)、アクセスしようとしています両方とものアカウントで、ハッシュの一致が確認できます。

ソルトとは、各ユーザーに固有の繰り返し可能なハッシングの前にパスワードに何かが行われる場所です。塩は予測可能でなければならないので、ボブとジェーンの塩は乱数であるとしましょう。

ボブABCDEF123のパスワードをハッシュすると、JaneのABCDEF456とは異なるハッシュになります。

このは、ではありません。考慮すべきいくつかの他の事:

  • あり、この文脈での乱数のようなものは、いないだけで、暗号乱数を確保する - とどのようにランダムに彼らがすることは、エントロピーや他の楽しいことに関連し、複雑です。
  • bcryptのようなハッシュアルゴリズムは、計算コストが高くなるように設計されています。ハッシュ計算の速さは、ブルートフォースを妨げる主要な要素です。違う(言い訳)SHA2
  • ユーザーが塩を投稿(または知ること)する理由はありません。

通常、十分に強調されていないもう一つの観察...このような話題についてインターネットで読んだことは決して信用すべきではありません。理解が不十分な人が多すぎます(私は自分自身と考えています) 。それで、これを自分でやらない理由としてとらえてください。それを行う方法のガイドではありません。

関連する問題