Oracle 在PL/SQL中滚动我自己的PKCS7填充

Oracle 在PL/SQL中滚动我自己的PKCS7填充,oracle,encryption,plsql,bit-manipulation,pkcs#7,Oracle,Encryption,Plsql,Bit Manipulation,Pkcs#7,我需要在PL/SQL+Oracle中使用过时的DBMS_OBFUSCATION_工具包包进行一些加密,但是如果在Java和Javascript中都是一个单词,那么它必须是可解密的。Java和JS解密用于PKCS7/PCKS5填充。我认为实现零填充很简单,我可以更改Java和JS,但我不知道零填充是否是不可逆的 因此,我想推出自己的PKCS7,但在生成正确的输出时遇到了一些问题。这段代码将我所拥有的按大小与DBMS_CRYPTO的输出进行比较,DBMS_CRYPTO实现了PKCS5,但由于权限问题

我需要在PL/SQL+Oracle中使用过时的DBMS_OBFUSCATION_工具包包进行一些加密,但是如果在Java和Javascript中都是一个单词,那么它必须是可解密的。Java和JS解密用于PKCS7/PCKS5填充。我认为实现零填充很简单,我可以更改Java和JS,但我不知道零填充是否是不可逆的

因此,我想推出自己的PKCS7,但在生成正确的输出时遇到了一些问题。这段代码将我所拥有的按大小与DBMS_CRYPTO的输出进行比较,DBMS_CRYPTO实现了PKCS5,但由于权限问题,并非所有员工都可以使用:

  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,该填充出现在填充后原始数据的末尾,但DBMS_CRYPTO产生的结果与DBMS_模糊处理_工具包不同。你知道为什么吗

提前谢谢

DBMS_CRYPTO的输出,它已实现PKCS5,但是 由于权限问题,不适用于所有员工:

  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;
其他员工不需要访问DBMS_CRYPTO,他们只需要访问您的功能。因此,您可以构建一个以特定且经批准的方式使用受限功能的功能,并使其广泛可用,而不会违反更广泛的权限问题

当然,我假设您的应用程序以一种合理的方式实现了模式,这允许在对象上分散最低限度的必要权限。如果你愿意的话,我最近写了一篇关于类似问题的博客文章

默认的IV是。。。我不知道,但是OBFS工具包和DBMS_CRYPTO有一个不同的版本。我只需要指定它,我使用0 IV进行测试。此外,OBFS的默认值是2键3des,因此我需要which=>1将其更改为3key。谢谢你的帮助

编辑:
由于对PKCS7/5规范的错误解释,原始解决方案实际上在长度为%8==0的字符串上失败。。。我已经更新了上面的解决方案,以显示整个/功能代码。

您可能是正确的,但不幸的是,根据我的老板,这是唯一的选择:/