3DES を使用してデータを暗号化および復号化する、PL/SQL で記述されたレガシー アプリケーションがあります。次に、Ruby アプリから同様の暗号化を実行する必要があります。最終的に、結果のハッシュは、既存のアルゴリズムを使用して同じ PL/SQL アプリケーションで復号化する必要があります。
問題は、PL/SQL と Ruby で異なる暗号化結果を取得していることです。その理由はわかりません。
まず、PL/SQL 暗号化の仕組みは次のとおりです。
DBMS_OBFUSCATION_TOOLKIT に関する Oracle のドキュメントから http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_obtool.htm
「Oracle の 3DES の実装は、外部暗号ブロック連鎖 (CBC) モードで、2 キーまたは 3 キーの実装をサポートしています。」
関数シグネチャ:
DBMS_OBFUSCATION_TOOLKIT.DES3Encrypt(
input_string IN VARCHAR2,
key_string IN VARCHAR2,
encrypted_string OUT VARCHAR2,
which IN PLS_INTEGER DEFAULT TwoKeyMode
iv_string IN VARCHAR2 DEFAULT NULL);
「= 0 (デフォルト) の場合、TwoKeyMode が使用されます。= 1 の場合、ThreeKeyMode が使用されます。」というパラメーターについて注意してください。これは、Ruby バージョンの暗号を選択するのに役立ちました。
アプリケーションがその呼び出しを行う方法は次のとおりです。
set serveroutput on;
declare
v_encrypted varchar2(100);
begin
dbms_obfuscation_toolkit.des3encrypt(
input_string => 'abcdefgh', -- data to encrypt
key_string => '16_byte_string_k', -- 16 byte = 128 bit key needed by DES3Encrypt
encrypted_string => v_encrypted,
iv_string => 'xxxxxxxx'); -- initialization vector
dbms_output.put_line( lower(utl_raw.cast_to_raw(v_encrypted)) );
-- prints 23ff779e88e2dbe1
end;
次に、Ruby で試しているのは次のとおりです。
OpenSSL::Cipher ドキュメント: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/Cipher.html
私に暗号名を与えるOpenSSLドキュメント:http ://www.openssl.org/docs/apps/enc.htmlから 「des-ede-cbc Two key triple DES EDE in CBC mode」
require 'openssl'
cipher = OpenSSL::Cipher.new('des-ede-cbc')
cipher.encrypt
input = 'abcdefgh'
cipher.key = '16_byte_string_k'
cipher.iv = 'xxxxxxxx'
# i noticed that cipher.update returns same length hash as PL/SQL
# if called without cipher.final, but you are not supposed to do that
#encrypted = cipher.update(input)
encrypted = cipher.update(input) + cipher.final
hex_representation = encrypted.unpack("H*")
puts hex_representation
# prints a5cfc96485d7203eb929c28ceb9fcd53
コードに示されているように、Ruby バージョンは異なるハッシュ値を計算します。なんで?それらを一貫させるために何を変更する必要がありますか?
よくわからない点:
- des-ede-cbc が実際に Oracle と同じであるかどうか。
- utl_raw.cast_to_raw と unpack("H*") が暗号化されたバイナリ データに対して同じことを行うかどうか。
- 正確に cipher.final が追加するものと、そのデータを PL/SQL に追加する同等の方法があるかどうか。
注: DES は安全ではなく、AES が取って代わったことを認識しています。私のユースケースでは、これらのハッシュが解読不能である必要はありません。重要な要件は、PL/SQL アプリが Ruby アプリによって生成されたハッシュを復号化できるように、ハッシュの一貫性を保つことです。