首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解密使用PHP加密的PL/SQL中的字符串?

问如何解密使用PHP加密的PL/SQL中的字符串?
EN

Stack Overflow用户
提问于 2022-04-26 06:33:43
回答 1查看 206关注 0票数 1

我对加密和解密技术很陌生。我需要解密从PHP服务器接收到的PL/SQL响应。加密方法是AES128 CBC。

PHP代码

代码语言:javascript
复制
$clear_text = "Secret Message";
$str        = "0962774221568619";
$key        = "0962774221568619";

$iv = str_pad($iv, 16, "\0");
$encrypt_text = openssl_encrypt($clear_text, "AES-128-CBC", $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($encrypt_text);

echo $data;

上面代码中的加密字符串是:87UMyOAog3rlmzorneakjA==

现在,我想在PL/SQL中解密这个字符串。在解密之前,我首先尝试通过复制PL/SQL中的PHP代码来加密相同的消息,如下所示。

使用PL/SQL的加密

代码语言:javascript
复制
DECLARE
   input_string       VARCHAR2 (200) :=  'Secret Message';
   output_string      VARCHAR2 (200);
   encrypted_raw      RAW (2000);             -- stores encrypted binary text
   decrypted_raw      RAW (2000);             -- stores decrypted binary text
   encrypted_string   VARCHAR2(1000);        
   num_key_bytes      NUMBER := 128/8;        -- key length 256 bits (32 bytes)
   key_bytes_raw      RAW (32);               -- stores 256-bit encryption key
   encryption_type    PLS_INTEGER :=          -- total encryption type
                            DBMS_CRYPTO.ENCRYPT_AES128
                          + DBMS_CRYPTO.CHAIN_CBC
                          + DBMS_CRYPTO.PAD_PKCS5;

   iv_raw             RAW (16);

BEGIN
   key_bytes_raw := UTL_I18N.STRING_TO_RAW ('0962774221568619',  'UTF8');
   iv_raw        := UTL_I18N.STRING_TO_RAW ('0962774221568619',  'UTF8');
   
   encrypted_raw := DBMS_CRYPTO.ENCRYPT
      (
         src => UTL_I18N.STRING_TO_RAW (input_string,  'UTF8'),
         typ => encryption_type,
         key => key_bytes_raw,
         iv  => iv_raw
      );

    DBMS_OUTPUT.PUT_LINE ('encrypted_raw: ' || encrypted_raw);    
    
    encrypted_string:= utl_raw.cast_to_varchar2(UTL_ENCODE.BASE64_ENCODE(encrypted_raw));
    
    DBMS_OUTPUT.PUT_LINE ('encrypted_string: ' || encrypted_string);
END;

输出

encrypted_raw: 0C36016A23FE45D8C62C50615336E5C6

encrypted_string: DDYBaiP+RdjGLFBhUzblxg=

这里,我从PHP和PL/SQL获得了不同的加密字符串。我不确定,但我认为PL/SQL中的PHP代码复制是不正确的。

使用下面的代码,我能够解密从PL/SQL加密的字符串。

代码语言:javascript
复制
DECLARE
   output_string      VARCHAR2 (200);
   encrypted_raw      RAW (2000);             -- stores encrypted binary text
   decrypted_raw      RAW (2000);             -- stores decrypted binary text
   num_key_bytes      NUMBER := 128/8;        -- key length 256 bits (32 bytes)
   key_bytes_raw      RAW (32);               -- stores 256-bit encryption key
   encryption_type    PLS_INTEGER :=          -- total encryption type
                            DBMS_CRYPTO.ENCRYPT_AES128
                          + DBMS_CRYPTO.CHAIN_CBC
                          + DBMS_CRYPTO.PAD_PKCS5;

   iv_raw             RAW (16);

BEGIN
   encrypted_raw := '0C36016A23FE45D8C62C50615336E5C6'; 
   key_bytes_raw := UTL_I18N.STRING_TO_RAW ('0962774221568619',  'UTF8');
   iv_raw        := UTL_I18N.STRING_TO_RAW ('0962774221568619',  'UTF8');
   
     decrypted_raw := DBMS_CRYPTO.DECRYPT
      (
         src => encrypted_raw,
         typ => encryption_type,
         key => key_bytes_raw,
         iv  => iv_raw
      );

   output_string := UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8');

   DBMS_OUTPUT.PUT_LINE ('Decrypted string: ' || output_string);
END;

输出:秘密消息

这很好,但我在解密从PHP加密的字符串时面临挑战。

更新

我忘记在用于加密字符串的PHP代码中分配一个IV值。感谢“topaco”和“BartoszOlchowik”指出了这个错误。

更新代码

代码语言:javascript
复制
$clear_text = "Secret Message";
$iv         = "0962774221568619";
$key        = "0962774221568619";

$iv = str_pad($iv, 16, "\0");
$encrypt_text = openssl_encrypt($clear_text, "AES-128-CBC", $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($encrypt_text);

echo $data;

加密字符串: DDYBaiP+RdjGLFBhUzblxg==

PL/SQL

代码语言:javascript
复制
DECLARE
   encrypted_string   VARCHAR2(1000):= 'DDYBaiP+RdjGLFBhUzblxg=='; -- Encrypted string from php
   output_string      VARCHAR2 (200);
   encrypted_raw      RAW (2000);             -- stores encrypted binary text
   decrypted_raw      RAW (2000);             -- stores decrypted binary text
          
   num_key_bytes      NUMBER := 128/8;        -- key length 256 bits (32 bytes)
   key_bytes_raw      RAW (32);               -- stores 256-bit encryption key
   encryption_type    PLS_INTEGER :=          -- total encryption type
                            DBMS_CRYPTO.ENCRYPT_AES128
                          + DBMS_CRYPTO.CHAIN_CBC
                          + DBMS_CRYPTO.PAD_PKCS5;

   iv_raw             RAW (16);

BEGIN
   key_bytes_raw := UTL_I18N.STRING_TO_RAW ('0962774221568619',  'UTF8');
   iv_raw        := UTL_I18N.STRING_TO_RAW ('0962774221568619',  'UTF8');
    
   --convert base64 encrypted string from php to raw
   encrypted_raw:= UTL_ENCODE.BASE64_DECODE(utl_raw.cast_to_raw(encrypted_string));
   
   decrypted_raw := DBMS_CRYPTO.DECRYPT
                    ( src => encrypted_raw,
                      typ => encryption_type,
                      key => key_bytes_raw,
                      iv  => iv_raw );
                      
   output_string := UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8');
   DBMS_OUTPUT.PUT_LINE ('Decrypted string: ' || output_string);    
END;

输出:解密字符串:秘密消息

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-27 13:12:31

您必须声明相同的加密数据才能正确解密。

在您的PLSQL代码中,IV变量的值与IV声明的值不同,因此您将无法解密PLSQL中的数据,而您在IV中使用不同的IV加密了这些数据。

在PLSQL中使用与PHP相同的IV值可以解决这个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72009327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档