我需要使用过时的DBMS_OBFUSCATION_TOOLKIT包在PL / SQL + Oracle中进行一些加密,但它必须在Java和Javascript中可解密(如果这甚至是一个单词)。 Java和JS解密用于PKCS#7 / PCKS#5填充。实现零填充很简单(我认为),我可以改变Java和JS,但我不知道我是否会遇到零填充不可逆转的问题。
因此,我想推出自己的PKCS#7,但是我在制作正确的输出方面遇到了一些麻烦。此代码将我所拥有的大小与DBMS_CRYPTO的输出进行比较,后者已实施PKCS#5,但由于权限问题而无法供所有员工使用:
FUNCTION DESWithPKCS5Padding(trash VARCHAR2)
RETURN VARCHAR2
IS
lv_encrypted_data VARCHAR2 (2000);
lv_decrypted_data VARCHAR2 (2000);
piv_str VARCHAR2 (2000) := 'apples';
piv_pass_key VARCHAR2 (2000) := 'testForNathan123testForN';
a_var VARCHAR2 (100);
num_padding_bytes Int;
padding_bytes raw(100);
test_byte raw(1);
zero_byte raw(1);
piv_raw raw(2000);
piv_raw_orig raw(2000);
error_in_input_buffer_length EXCEPTION;
PRAGMA EXCEPTION_INIT (error_in_input_buffer_length, -28232);
input_buffer_length_err_msg VARCHAR2 (100) :=
BEGIN
dbms_output.Put_line ('Input_string->:'
|| piv_str );
-- Since 3DES needs data to be in multiples of 8 bytes we had pad the data, if the
-- data did not meet the 8 bytes boundary requirement.
num_padding_bytes := MOD(Length(piv_str),8);
piv_raw_orig := utl_raw.cast_to_raw(piv_str);
IF (num_padding_bytes) != 0 THEN
padding_bytes := '';
zero_byte := '0';
test_byte := utl_raw.cast_to_raw(8-num_padding_bytes);
test_byte := utl_raw.bit_and(test_byte, '0F');
for lcntr in 1..8-num_padding_bytes
loop
padding_bytes := UTL_RAW.CONCAT(padding_bytes, test_byte);
end loop;
piv_raw := utl_raw.concat(utl_raw.cast_to_raw(piv_str), padding_bytes);
END IF;
dbms_output.put_line('Without padding: ' || piv_raw_orig);
dbms_output.put_line('After padding: '|| piv_raw);
lv_encrypted_data := dbms_obfuscation_toolkit.Des3encrypt (
input => piv_raw, key => utl_raw.cast_to_raw(piv_pass_key),
which => 1);
dbms_output.Put_line ('Encrypted Data OBFS: '
|| lv_encrypted_data);
lv_encrypted_data := dbms_crypto.encrypt (src => piv_raw_orig,
KEY => utl_raw.cast_to_raw(piv_pass_key), typ => dbms_crypto.des3_cbc_pkcs5);
dbms_output.Put_line ('Encrypted Data CRYPTO: '
|| (lv_encrypted_data));
lv_decrypted_data := dbms_crypto.Decrypt (src => lv_encrypted_data,
KEY => utl_raw.cast_to_raw(piv_pass_key), typ => dbms_crypto.des3_cbc_pkcs5);
dbms_output.Put_line('Decrypted: ' || utl_raw.cast_to_varchar2(lv_decrypted_data));
END;
输出:
Input_string->:apples
Without padding: 6170706C6573
After padding: 6170706C65730202
Encrypted Data OBFS: 36DEFCBBC60BC58A
Encrypted Data CRYPTO: CF7676DF282DCC5C
Decrypted: apples
如您所见,看起来填充正确应用(0202出现在填充RAW后),但DBMS_CRYPTO产生的结果与DBMS_OBFUSCATION_TOOLKIT不同。有什么想法吗?
提前致谢!
答案 0 :(得分:0)
“DBMS_CRYPTO的输出,已实施PKCS#5,但是 由于权限问题,所有员工无法使用:“
其他员工不需要访问DBMS_CRYPTO,他们只需要访问您的功能。因此,您可以构建一个以特定和批准的方式使用受限功能的功能,并使其广泛可用,而不会违反更广泛的权限问题。
当然,我假设您的应用程序以合理的方式实现了模式,这允许在对象上分散最小的必要特权。如果您想find out more,我最近就类似问题撰写了一篇博客文章。
答案 1 :(得分:0)
function ApplyPKCS5Padding (v_to_pad raw)
return raw
IS
a_var VARCHAR2 (100);
num_padding_bytes Int;
padding_bytes raw(100);
test_byte raw(1);
zero_byte raw(1);
output raw(2000);
BEGIN
-- Since DES needs data to be in multples of 8 bytes we pad the data, if the
-- data did not meet the 8 bytes boundry requirment.
num_padding_bytes := MOD(Length(utl_raw.cast_to_varchar2(v_to_pad)),8);
output := v_to_pad;
IF (num_padding_bytes) != 0 THEN
padding_bytes := '';
zero_byte := '0';
test_byte := utl_raw.cast_to_raw(8-num_padding_bytes);
test_byte := utl_raw.bit_and(test_byte, '0F');
for lcntr in 1..8-num_padding_bytes
loop
padding_bytes := UTL_RAW.CONCAT(padding_bytes, test_byte);
end loop;
output := utl_raw.concat(v_to_pad, padding_bytes);
ELSE
padding_bytes := '0808080808080808';
output := utl_raw.concat(v_to_pad, padding_bytes);
END IF;
return output;
END;
默认IV是......我不知道,但OBFS工具包和DBMS_CRYPTO有不同的一个。我只需要指定它,我用0 IV进行测试。此外,OBFS的默认值是2键3des,因此我需要which => 1
将其更改为3key。谢谢你的帮助!
编辑: 最初的解决方案"由于对PKCS#7/5规范的误解,实际上在长度为%8 == 0的字符串上失败了...我已经更新了上面的解决方案以显示整个/正常运行的代码。