我对加密和解密技术很陌生。我需要解密从PHP服务器接收到的PL/SQL响应。加密方法是AES128 CBC。
PHP代码
$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的加密
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”指出了这个错误。
更新代码
$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
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;输出:解密字符串:秘密消息
发布于 2022-04-27 13:12:31
您必须声明相同的加密数据才能正确解密。
在您的PLSQL代码中,IV变量的值与IV声明的值不同,因此您将无法解密PLSQL中的数据,而您在IV中使用不同的IV加密了这些数据。
在PLSQL中使用与PHP相同的IV值可以解决这个问题。
https://stackoverflow.com/questions/72009327
复制相似问题