入力と同じプレーンテキストとパスフレーズを使用してPostgreSQLのpgp_sym_encrypt
コマンドを実行すると、異なる結果が得られます。同じパスフレーズでこれらの異なる結果を復号化すると、正しいプレーンテキストが返されます。
暗号化機能が同じパスフレーズの同じ平文に対して常に異なる結果をもたらす理由を理解したいのですが?
平文、一意キー、セッションキーでも同じ問題が発生します。
異なる暗号化結果が得られる同じ列に一意の制約を作成したため、同じテキストに新しいレコードを複数回追加できます。
例:
pgp_sym_encrypt('12345','key1')
上記のコマンドを2回実行すると、異なる出力が得られ、異なる出力を復号化すると、同じ平文が返されます。
OpenPGPでは、メッセージはパスフレーズで直接暗号化されません。代わりに、メッセージの対称暗号化のキーとしてランダムセッションキーが生成されます。
このセッションキーは、パスフレーズを使用して暗号化されるようになりました。このような2段階のアプローチを適用することで、メッセージを1回暗号化できますが、セッションキーの暗号化されたコピーを1回追加することで、異なる秘密キーまたはパスフレーズを使用した復号化が可能になります。 OpenPGPメッセージがどのように作成されるかをより深く理解するには、 RFC 4880、OpenPGP と、暗号化されたメッセージのgpg --list-packets
およびpgpdump
の出力を参照してください(どちらも印刷されます)。 OpenPGPパケットに関する情報)。
さらに、各メッセージにはランダムなバイトが埋め込まれるため、メッセージもまったく異なります。最後に、暗号化されたメッセージには暗号化タイムスタンプが格納されます。これは、まったく同じ秒に2回暗号化しない限り、明らかに異なります。
同じメッセージを2回暗号化するときに異なる出力を持つことは、非常に重要です。2つのメッセージが実際には同じメッセージであるという情報は、多くの場合、すでに問題になっています。ランダムなセッションキーとパディングを使用することにより、攻撃者は複数のメッセージを入手した場合、メッセージの内容を推測することはできません。
メッセージに一意の制約を設定する必要がある場合は、メッセージの暗号化ハッシュ合計(SHA-256など)を計算し、これを追加で保存します(暗号化されたメッセージの代わりに、ハッシュ合計の一意の制約を計算します)。