10

OK、たぶん月曜日が悪いのですが、次のニーズがあり、部分的な解決策がたくさん見られますが、これを必要とするのは私が初めてではないはずです。明らかなことを見逃しています。

$client には 50 ~ 500 バイト相当のバイナリ データがあり、これを URL の途中に挿入し、顧客のブラウザに往復させる必要があります。これは URL の一部であるため、GET URL の 1K の「理論上の」制限に直面しています。また、$client は、顧客がデータをデコードしたり、検出されずに改ざんしたりすることを望んでいません。$client もサーバー側に何も保存しないことを好むため、これは完全にスタンドアロンである必要があります。エンコーディングとデコーディングの両方で、Perl コードで高速でなければなりません。

最後のステップは base64 にできると思います。しかし、最も理にかなった暗号化とハッシュ化の手順は何ですか?

4

4 に答える 4

5

CatアプリCrypt::Utilに、メール確認リンク用にユーザーのメールアドレスをエンコード/デコードするために使用するコードがあります。

秘密鍵Crypt::Utilを使用してモデルを設定しました。Catalyst::Model::Adaptor次に、私のコントローラーでは、送信側に次のロジックがあります。

my $cu = $c->model('CryptUtil');
my $token = $cu->encode_string_uri_base64( $cu->encode_string( $user->email ) );
my $url = $c->uri_for( $self->action_for('verify'), $token );

このリンクをに送信し、$user->emailクリックすると次のリンクが使用されます。

my $cu = $c->model('CryptUtil');
if ( my $id = $cu->decode_string( $cu->decode_string_uri_base64($token) ) ) {
    # handle valid link
} else { 
    # invalid link
}

これは基本的edaniteに、別の回答で提案されたものです。トークンを形成するために使用するデータが、ファイナル$urlが任意の制限を超えないようにする必要があります。

于 2010-05-24T23:15:01.603 に答える
4

秘密鍵を作成してサーバーに保存します。複数のサーバーがあり、リクエストが同じサーバーに戻ることが保証されていない場合。すべてのサーバーで同じキーを使用する必要があります。このキーは定期的にローテーションする必要があります。

データをCBC(Cipher Block Chaining)モードで暗号化する場合(Crypt :: CBCモジュールを参照)、暗号化のオーバーヘッドは最大2ブロック(1つはIV用、もう1つはパディング用)です。128ビット(つまり16バイト)のブロックは一般的ですが、普遍的ではありません。ブロック暗号としてAES(別名Rijndael)を使用することをお勧めします。

データが変更されていないことを確認するには、データを認証する必要があります。アプリケーションのセキュリティによっては、メッセージをハッシュし、暗号化するプレーンテキストにハッシュを含めるだけで十分な場合があります。これは、攻撃者が対称暗号化キーを知らずにメッセージに一致するようにハッシュを変更できないことに依存します。暗号に128ビットのキーを使用している場合は、SHA-256のような256ビットのハッシュを使用します(これにはダイジェストモジュールを使用できます)。リクエストが複数回繰り返されないように、タイムスタンプなどの他のものをデータに含めることもできます。

于 2010-05-24T23:09:45.313 に答える
3

ここに 3 つのステップがあります。まず、データを圧縮してみます。データが非常に少ない場合、bzip2 はおそらく 5 ~ 20% 節約できます。データが大きくならないようにガードを入れます。このステップはあまり価値がないかもしれません。

use Compress::Bzip2 qw(:utilities);
$data = memBzip $data;

データ内のキーと値の長さを手動で短くすることもできます。たとえば、first_nameに減らすことができますfname

次に、暗号化します。お気に入りの暗号を選択して、Crypt::CBC を使用します。ここでは Rijndael を使用します。これは、NSA にとって十分なためです。ベンチマークを実行して、パフォーマンスとセキュリティの最適なバランスを見つける必要があります。

use Crypt::CBC;
my $key = "SUPER SEKRET";
my $cipher = Crypt::CBC->new($key, 'Rijndael');
my $encrypted_data = $cipher->encrypt($data);

キーをサーバーに保存する必要があります。保護されたファイルに入れるだけで十分であり、そのファイルを演習として残します。サーバーに何も保存できないと言うとき、これにはキーが含まれていないと思います。

最後に、Base 64 でエンコードします。+ と / の代わりに - と _ を使用する変更された URL セーフな Base 64 を使用すると、Base 64 文字列でこれらの文字を URL エンコードするスペースを費やす必要がなくなります。 MIME::Base64::URLSafeがそれをカバーしています。

use MIME::Base64::URLSafe;
my $safe_data = urlsafe_b64encode($encrypted_data);

次に、必要に応じて URL に貼り付けます。それを読み込むプロセスを逆にします。

あなたはサイズで安全でなければなりません。暗号化するとデータのサイズが増加しますが、おそらく 25% 未満です。Base 64 では、データのサイズが 3 分の 1 増加します (2^8 ではなく 2^6 としてエンコードされます)。これにより、500 バイトのエンコードが 1K 内に快適に収まるはずです。

于 2010-05-24T23:30:23.530 に答える
-1

どの程度安全である必要がありますか? 長いランダムな文字列でデータを xor し、改ざんを検出するために別のシークレット ソルトを使用してロット全体の MD5 ハッシュを追加することはできますか?

私はそれを銀行のデータには使用しませんが、ほとんどの Web ではおそらく問題ないでしょう...

大きい

于 2010-05-24T22:55:16.580 に答える