如何解密 PL/SQL 中使用 PHP 加密的字符串?
How to decrypt a string in PL/SQL that is encrypted using PHP?
我不熟悉加密和解密技术。我需要解密从 PHP 服务器收到的 PL/SQL 中的响应。加密方式为AES128 CBC。
PHP代码
$clear_text = "Secret Message";
$str = "0962774221568619";
$key = "0962774221568619";
$iv = str_pad($iv, 16, "[=12=]");
$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
加密
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.
加密的字符串
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 指出这个错误。
更新代码
PHP
$clear_text = "Secret Message";
$iv = "0962774221568619";
$key = "0962774221568619";
$iv = str_pad($iv, 16, "[=15=]");
$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
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;
输出:解密后的字符串:Secret Message
您必须声明相同的加密数据才能正确解密。
在您的 PLSQL 代码中,IV
变量的值与 PHP 中声明的 IV
不同,因此您将无法解密 PLSQL 中的数据,您使用不同的 IV
在 PHP.
在 PLSQL 中使用与 PHP 中相同的 IV
值将解决问题。
我不熟悉加密和解密技术。我需要解密从 PHP 服务器收到的 PL/SQL 中的响应。加密方式为AES128 CBC。
PHP代码
$clear_text = "Secret Message";
$str = "0962774221568619";
$key = "0962774221568619";
$iv = str_pad($iv, 16, "[=12=]");
$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
加密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.
加密的字符串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 指出这个错误。
更新代码
PHP
$clear_text = "Secret Message";
$iv = "0962774221568619";
$key = "0962774221568619";
$iv = str_pad($iv, 16, "[=15=]");
$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
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;
输出:解密后的字符串:Secret Message
您必须声明相同的加密数据才能正确解密。
在您的 PLSQL 代码中,IV
变量的值与 PHP 中声明的 IV
不同,因此您将无法解密 PLSQL 中的数据,您使用不同的 IV
在 PHP.
在 PLSQL 中使用与 PHP 中相同的 IV
值将解决问题。