OpenSSL 在 Windows 上不起作用,错误0x02001003 0x2006D080 0x0E064002

2022-08-30 10:25:06

问题:OpenSSL在我的Windows环境中不起作用。OpenSSL 会重复报告0x02001003、0x2006D080和0x0E064002的错误。

环境:

Windows NT x 6.1 build 7601 (Windows 7 Business Edition Service Pack 1) i586
Apache/2.4.4 (Win32)
PHP/5.4.13 x86
PHP Directory: E:\wamp\php\
Virtual Host Directory: E:\Projects\1\public_html

我尝试过:

  • 安装说明 http://www.php.net/manual/en/openssl.installation.php
  • 菲律宾比索.ini extension=php_openssl.dll
  • Openssl.cnf E:\wamp\php\extras\openssl.cnf
  • %路径% E:\wamp\php
  • 重新 启动
  • phpinfo:
    ----OpenSSL 支持已启用
    ----OpenSSL 库版本 OpenSSL 1.0.1e 11 Feb 2013
    ----OpenSSL Header Version OpenSSL 0.9.8y 5 Feb 2013
  • 使用和不指定配置configargs
  • 在 apache 配置中使用和不指定<Directory E:\wamp\php\extras>
  • 复制到虚拟主机public_html,指向该,但仍然得到相同的错误openssl.cnf
  • error_log未登录任何内容
  • 研究:我花了最后两天的时间研究这个问题,很惊讶没有更多的信息,所以我在这里发布。似乎是OpenSSL配置或apache / php无法正确读取配置的问题。

法典:

$privateKey = openssl_pkey_new();
while($message = openssl_error_string()){
    echo $message.'<br />'.PHP_EOL;
}

结果:

error:02001003:system library:fopen:No such process
error:2006D080:BIO routines:BIO_new_file:no such file
error:0E064002:configuration file routines:CONF_load:system lib
error:02001003:system library:fopen:No such process
error:2006D080:BIO routines:BIO_new_file:no such file
error:0E064002:configuration file routines:CONF_load:system lib

手动打开SSL:

E:\wamp\apache\bin>openssl.exe pkey
WARNING: can't open config file: c:/openssl-1.0.1e/ssl/openssl.cnf

E:\wamp\apache\bin>set OPENSSL_CONF="E:\wamp\php\extras\openssl.cnf"

E:\wamp\apache\bin>openssl.exe pkey
3484:error:0200107B:system library:fopen:Unknown error:.\crypto\bio\bss_file.c:169:fopen('"E:\wamp\php\extras\openssl.cnf"','rb')
3484:error:2006D002:BIO routines:BIO_new_file:system lib:.\crypto\bio\bss_file.c:174:
3484:error:0E078002:configuration file routines:DEF_LOAD:system lib:.\crypto\conf\conf_def.c:199:

编辑:

  1. 多亏了@Gordon我现在可以看到open_ssl错误openssl_error_string
  2. 完全卸载 EasyPHP。手动安装的 PHP/Apache 稳定版本。同样的结果!绝对是我在Windows上实现openssl时做错了什么。
  3. OpenSSL Manual 部分...其他错误信息

最后的想法:
我设置了一个linux盒子,我得到了同样的错误。经过一番研究,我发现即使它在openssl_pkey_new它最终创建了我的测试p12文件。长话短说,错误具有误导性,它必须更多地处理您如何使用openssl函数而不是服务器端配置。

最终代码:

// Create the keypair
$res=openssl_pkey_new();

// Get private key
openssl_pkey_export($res, $privkey);

// Get public key
$pubkey=openssl_pkey_get_details($res);
$pubkey=$pubkey["key"];

// Actual file
$Private_Key = null;
$Unsigned_Cert = openssl_csr_new($Info,$Private_Key,$Configs);
$Signed_Cert = openssl_csr_sign($Unsigned_Cert,null,$Private_Key,365,$Configs);
openssl_pkcs12_export_to_file($Signed_Cert,"test.p12",$Private_Key,"123456");

靠近。

一年后...

因此,一年后我发现自己再次这样做,无论我在计算机上或在脚本执行期间设置了什么PATH变量,它都会不断出错,因为找不到文件。我能够通过在 中传入数组中的参数来解决它。下面是一个函数,用于测试成功使用 OpenSSL 的能力:configconfig_argsopenssl_pkey_new

    /**
     * Tests the ability to 1) create pub/priv key pair 2) extract pub/priv keys 3) encrypt plaintext using keys 4) decrypt using keys
     * 
     * @return boolean|string False if fails, string if success
     */
    function testOpenSSL($opensslConfigPath = NULL)
    {
        if ($opensslConfigPath == NULL)
        {
            $opensslConfigPath = "E:/Services/Apache/httpd-2.4.9-win32-VC11/conf/openssl.cnf";
        }
        $config = array(
            "config" => $opensslConfigPath,
            "digest_alg" => "sha512",
            "private_key_bits" => 4096,
            "private_key_type" => OPENSSL_KEYTYPE_RSA,
        );

        $res = openssl_pkey_new($config); // <-- CONFIG ARRAY
        if (empty($res)) {return false;}

        // Extract the private key from $res to $privKey
        openssl_pkey_export($res, $privKey, NULL, $config); // <-- CONFIG ARRAY

        // Extract the public key from $res to $pubKey
        $pubKey = openssl_pkey_get_details($res);
        if ($pubKey === FALSE){return false;}

        $pubKey = $pubKey["key"];

        $data = 'plaintext data goes here';

        // Encrypt the data to $encrypted using the public key
        $res = openssl_public_encrypt($data, $encrypted, $pubKey);
        if ($res === FALSE){return false;}

        // Decrypt the data using the private key and store the results in $decrypted
        $res = openssl_private_decrypt($encrypted, $decrypted, $privKey);
        if ($res === FALSE){return false;}

        return $decrypted;
    }

    // Example usage:
    $res = testOpenSSL();
    if ($res === FALSE)
    {
        echo "<span style='background-color: red;'>Fail</span>";
    } else {
        echo "<span style='background-color: green;'>Pass: ".$res."</span>";
    }

答案 1

下面的代码按预期工作。但是如果你在openssl方法之后运行,它会显示一些通知,我无法找到文档。openssl_error_string()error:0E06D06C:configuration file routines:NCONF_get_string:no value

另请注意,根据 http://www.php.net/manual/en/function.openssl-error-string.php,您可能会看到错误引导错误,因为错误消息已排队:

使用此函数检查错误时要小心,因为它似乎从>错误的缓冲区读取,其中可能包括来自使用 openssl > 函数的其他脚本或进程的错误。(我很惊讶地发现它在调用任何> openssl_*函数之前返回错误消息)

<?php
/* Create the private and public key */
$res = openssl_pkey_new();
openssl_error_string(); // May throw error even though its working fine!

/* Extract the private key from $res to $privKey */
openssl_pkey_export($res, $privKey);
openssl_error_string(); // May throw error even though its working fine!

/* Extract the public key from $res to $pubKey */
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];

$data = 'i.amniels.com is a great website!';

/* Encrypt the data using the public key
 * The encrypted data is stored in $encrypted */
openssl_public_encrypt($data, $encrypted, $pubKey);

/* Decrypt the data using the private key and store the
 * result in $decrypted. */
openssl_private_decrypt($encrypted, $decrypted, $privKey);

echo $decrypted;
?>

答案 2

这里有几件事:

%PATH%还应该包含 windows 和 system32 所以你的 %PATH% 应该看起来像和 in 应该是 openssl dll 文件c:\windows;c:\windows\system32;E:\wamp\phpe:\wamp\php

还尝试使用与标题版本匹配的opensl版本,此处下载32位此处下载64位0.9.8y 5 Feb 2013

这段代码似乎对我有用:

// Create the keypair
$res=openssl_pkey_new();

// Get private key
openssl_pkey_export($res, $privkey);

// Get public key
$pubkey=openssl_pkey_get_details($res);
$pubkey=$pubkey["key"];
$Info = array(
    "countryName" => "UK",
    "stateOrProvinceName" => "Somerset",
    "localityName" => "Glastonbury",
    "organizationName" => "The Brain Room Limited",
    "organizationalUnitName" => "PHP Documentation Team",
    "commonName" => "Wez Furlong",
    "emailAddress" => "wez@example.com"
);

// Actual file
$Private_Key = null;
$Unsigned_Cert = openssl_csr_new($Info,$Private_Key);
$Signed_Cert = openssl_csr_sign($Unsigned_Cert,null,$Private_Key,365);
openssl_pkcs12_export_to_file($Signed_Cert,"test.p12",$Private_Key,"123456");

推荐