You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用openssl_public_decrypt遇"解密数据非字符串"错误,如何获取正确结果?

问题分析与解决

错误原因

你遇到的"Decrypted data is not a string"错误主要由以下几个问题导致:

  • 输出变量未初始化:decrypted_zval在传递给openssl_public_decrypt前没有被初始化,函数无法正确写入解密结果。
  • 引用参数传递错误:使用ZVAL_NEW_REF创建引用的方式不符合PHP扩展的参数传递规范,导致函数无法正确修改引用变量。
  • 忽略Base64解码失败场景:php_base64_decode_ex可能返回NULL(输入无效Base64时),此时继续调用解密函数会引发异常。
  • 未返回实际解密结果:当前代码仅返回布尔值,没有将解密后的字符串返回给调用者。

修正后的代码

#include "php.h"
#include "ext/standard/info.h"
#include "ext/standard/php_string.h"
#include "ext/standard/base64.h"

PHP_FUNCTION(my_openssl_public_decrypt) {
    zend_string *data, *public_key;
    zval func_name;
    zval result;
    zval params[3];
    zval decrypted_zval;

    // 解析输入参数
    if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &data, &public_key) == FAILURE) {
        RETURN_FALSE;
    }

    // Base64解码,处理解码失败的情况
    zend_string *raw_data = php_base64_decode_ex((const unsigned char*)ZSTR_VAL(data), ZSTR_LEN(data), 0);
    if (!raw_data) {
        php_error_docref(NULL, E_WARNING, "Invalid Base64 data");
        RETURN_FALSE;
    }

    // 初始化函数名字符串
    ZVAL_STR(&func_name, zend_string_init("openssl_public_decrypt", strlen("openssl_public_decrypt"), 0));

    // 初始化输出变量为NULL,准备作为引用传递
    ZVAL_NULL(&decrypted_zval);
    // 将输出变量包装为引用类型,传递给openssl_public_decrypt
    ZVAL_REF(&params[1], &decrypted_zval);
    ZVAL_STR(&params[0], raw_data);
    ZVAL_STR(&params[2], public_key);

    // 调用PHP的openssl_public_decrypt函数
    if (call_user_function(EG(function_table), NULL, &func_name, &result, 3, params) == FAILURE) {
        php_error_docref(NULL, E_WARNING, "Failed to call openssl_public_decrypt");
        zend_string_release(raw_data); // 释放资源
        RETURN_FALSE;
    }

    // 释放Base64解码后的字符串资源
    zend_string_release(raw_data);

    // 检查解密是否成功
    if (Z_TYPE(result) == IS_TRUE) {
        // 确保解密结果是字符串类型
        if (Z_TYPE(decrypted_zval) == IS_STRING) {
            // 返回解密后的字符串给PHP层
            RETURN_STR(Z_STR(decrypted_zval));
        } else {
            php_error_docref(NULL, E_WARNING, "Decrypted data is not a string");
            RETURN_FALSE;
        }
    } else {
        php_error_docref(NULL, E_WARNING, "Decryption failed");
        RETURN_FALSE;
    }
}

关键修正点说明

  1. 初始化输出变量:用ZVAL_NULL(&decrypted_zval)初始化输出变量,确保它是一个有效的zval,让openssl_public_decrypt可以正确写入结果。
  2. 正确传递引用参数:使用ZVAL_REF将decrypted_zval包装为引用类型,符合PHP函数对引用参数的要求。
  3. 处理Base64解码失败:检查raw_data是否为NULL,避免无效数据进入解密流程。
  4. 返回解密结果:将解密后的字符串通过RETURN_STR(Z_STR(decrypted_zval))返回给PHP层,满足获取解密结果的需求。
  5. 资源释放:在合适的地方释放raw_data,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Dylan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:03:12