【问题标题】:OpenSSL not working on Windows, errors 0x02001003 0x2006D080 0x0E064002OpenSSL 在 Windows 上不起作用,错误 0x02001003 0x2006D080 0x0E064002
【发布时间】:2013-03-11 14:24:05
【问题描述】:

问题: 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
  • PHP.ini extension=php_openssl.dll
  • Openssl.cnf E:\wamp\php\extras\openssl.cnf
  • %PATH% E:\wamp\php
  • 重新启动
  • phpinfo:
    ----OpenSSL 支持启用
    ----OpenSSL 库版本 OpenSSL 1.0.1e 2013 年 2 月 11 日
    ----OpenSSL 标头版本 OpenSSL 0.9.8y 2013 年 2 月 5 日
  • configargs 中指定和不指定 config
  • 在 apache 配置中指定和不指定 <Directory E:\wamp\php\extras>
  • 已将 openssl.cnf 复制到 virtualhost public_html,指出了这一点,但仍然出现相同的错误
  • 没有登录 error_log
  • 研究:我在过去 2 天里一直在研究这个,很惊讶没有更多的信息,所以我在这里发帖。似乎是 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

手动 OpenSSL:

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,我现在可以看到使用openssl_error_string 的open_ssl 错误
  2. 完全卸载 EasyPHP。手动安装稳定版本的 PHP/Apache。结果一样!在 Windows 上实现 openssl 绝对是我做错了。
  3. OpenSSL 手动部分...附加错误信息

最后的想法:
我设置了一个 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_pkey_newconfig_args 数组中传入config 参数来解决它。这是一个测试能否成功使用 OpenSSL 的函数:

    /**
     * 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>";
    }

【问题讨论】:

  • 所以它似乎肯定是在读取 openssl.cnf 文件,如果我将 config 设置为一个不存在的文件,我不会收到文件错误。所以我认为问题出在 openssl.cnf、apache 权限或 openssl 二进制文件丢失/权限... /2days
  • 我必须把它放进去,除非你使用 MS 特定的产品,比如 MSSQL 和 .NET 的东西,否则请在服务器环境中使用 Linux。如果您无法为其设置盒子,请使用虚拟化(例如 vmware、virtualbox)
  • @Populus '改变你的操作系统' 不是现实世界的解决方案。
  • 但是您可以轻松制作虚拟环境。任何想在 Windows 上使用 Apache 的人都应该重新考虑他们的计划:x 所以我只能假设这是一个测试环境。
  • 这是一个开发环境。虽然生产将在 linux 中进行,但不幸的是,这是我坚持开发的环境。虽然我同意,但我也想找到答案,因为我知道这可以在 Windows 上运行。

标签: php apache apache2 openssl easyphp


【解决方案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% 应该看起来像 c:\windows;c:\windows\system32;E:\wamp\php 并且在 e:\wamp\php 中应该是 openssl dll 文件

    也可以尝试匹配头部版本0.9.8y 5 Feb 2013的openssl版本下载here for 32bithere for 64bit

    这段代码似乎对我有用:

    // 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");
    

    【讨论】:

      【解决方案3】:

      我遇到了类似的问题,对我来说,在脚本开头手动设置环境变量“OPENSSL_CONF”很有帮助。

      不知何故,环境变量设置不正确,或者没有通过我的 php(设置:AMPPS,Win7 64Bit)。

      下面使用的示例位置是您在标准 AMPPS 安装中必须使用的路径,因此如果您使用的是 AMPPS,只需复制和粘贴即可:

      putenv("OPENSSL_CONF=C:\Program Files (x86)\Ampps\php\extras\openssl.cnf");
      

      【讨论】:

      • 这对我不起作用,但在 config_args 数组中指定 openssl.cnf 的路径确实有效。
      【解决方案4】:

      如果您使用的是 Apache 2.4 + mod_fcgid,您可以通过在 httpd.conf 文件中添加 FcgidInitialEnv 来指定 OpenSSL conf 文件:

      # OPENSSL CONF
      FcgidInitialEnv OPENSSL_CONF "D:/apps/php70/extras/ssl/openssl.cnf"
      

      我没有使用 WAMP 等预配置包,我有来自 Apache Lounge 的 Apache 和来自 windows.php.net 的 PHP,并由我自己配置​​。

      【讨论】:

        【解决方案5】:

        清洁解决方案:

        1. 从这里下载 PHP Windows 二进制文件的存档(不管是哪个):http://windows.php.net/download
        2. 在里面找到文件 /extras/ssl/openssl.cnf
        3. 在某处提取 openssl.cnf(例如“C:/WEB/PHP/extras/ssl/openssl.cnf”)
        4. 使用您使用的路径添加全局系统变量OPENSSL_CONF(例如“C:\WEB\PHP\extras\openssl.cnf”(不带双引号))。

        您必须将路径添加到OPENSSL_CONF 系统变量。将其添加到 Path 系统变量是不够的!在 Windows 7 下,您可以在以下位置找到设置对话框:“控制面板 > 系统和安全 > 系统 > 高级系统设置(左侧菜单)> 高级(选项卡)> 环境变量...”。在那里添加变量OPENSSL_CONF

        使用前不需要准备 openssl.cnf 文件 - 它可以开箱即用。但是,如果您想微调设置,您可以。

        【讨论】:

          【解决方案6】:

          您是否通过此方法安装了 OpenSSL? 在 Windows 上安装 OpenSSL

          1. 转到http://gnuwin32.sourceforge.net/packages/openssl.htm,下载“二进制”的“安装”版本,openssl-0.9.7c-bin.exe。

          2. 双击 openssl-0.9.7c-bin.exe 将 OpenSSL 安装到 \local\gnuwin32 目录。

          3. 回到同一页面,下载“文档”的“安装”版本,并安装到同一目录。

          4. 打开命令行窗口,尝试以下命令: 代码:

              \local\gnuwin32\bin\openssl -help
              openssl:Error: '-help' is an invalid command.
          
              Standard commands
              asn1parse      ca             ciphers        crl            crl2pkcs7
              dgst           dh             dhparam        dsa            dsaparam
              enc            engine         errstr         gendh          gendsa
              genrsa         nseq           ocsp           passwd         pkcs12
              pkcs7          pkcs8          rand           req            rsa
              rsautl         s_client       s_server       s_time         sess_id
              smime          speed          spkac          verify         version
              x509
              ......
          

          如果您看到 OpenSSL 打印的命令列表,则说明您的安装已正确完成。

          【讨论】:

          【解决方案7】:

          在我的情况下,将文件复制到 c:\windows\system32 帮助了我

          libeay32.dll, ssleay32.dll

          可以在 OpenSSL_INSTALL_PATH\bin 中找到它们。

          【讨论】:

            【解决方案8】:
            <?php 
            
                     // also see  stackoverflow.com/questions/59195251/php-get-private-key-from-a-single-line-private-key 
                     // micmap.org/php-by-example/de/function/openssl_get_publickey
                     // best  stackoverflow.com/questions/15558321/openssl-not-working-on-windows-errors-0x02001003-0x2006d080-0x0e064002
                     // sandrocirulli.net/how-to-encrypt-and-decrypt-emails-and-files/
            
            
            
                     echo '<pre>';
            
            
                    function testOpenSSL($openssl_args)
                    {
            
                            $res = openssl_pkey_new($openssl_args); // <-- CONFIG ARRAY
                            openssl_error_string(); // May throw error even though its working fine!
                            if (empty($res)) {return false;}
                            $openssl_args['keysnew']=$res;
                                    //var_dump($res);echo '<br><br>';
            
            
                            // Extract the private key from $res to $privKey
                            openssl_pkey_export($res, $privKey, NULL, $openssl_args); // <-- CONFIG ARRAY
                            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);
                            openssl_error_string(); // May throw error even though its working fine!
                            if ($pubKey === FALSE){return false;}
                            $pubKey = $pubKey["key"];   
            
                            // Encrypt the data to $encrypted using the public key
                            $data = $openssl_args['data'];          
                            $res = openssl_public_encrypt($data, $encrypted, $pubKey);
                            if ($res === FALSE){return false;}
                                    #var_dump($res);exit; //bool
                            // 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;
                            $openssl_args['pub_key']=$pubKey;
                            $openssl_args['priv_key']=$privKey;
                            $openssl_args['encr']=$encrypted;
                            $openssl_args['decr']=$decrypted; 
            
                            return $openssl_args;
            
                    }
            
            
            
            
                    // try sam openssl.cnf   , most error on windows xampp
                    $try= 5;     
                    $openssl_cnf_path = array(
                        0=>'C:\xampp\apache\conf\openssl.cnf',   //11259 bytes
                        1=>'C:\xampp\apache\bin\openssl.cnf',   //11259 bytes
            
                        2=>'C:\xampp\php\windowsXamppPhp\extras\ssl\openssl.cnf',  //10909
                        3=>'C:\xampp\php\extras\ssl\openssl.cnf',   //10909 byes
                        4=>'C:\xampp\php\extras\openssl\openssl.cnf',   //9374 bytes
            
                        5=>'C:\Program Files\Git\usr\ssl\openssl.cnf',  //10909 bytes
                        6=>'C:\Program Files\Git\mingw64\ssl\openssl.cnf',  //10909 bytes
                        );
            
                    $data = ' todo in spin activate theme elementor-child plugin qw_casino ... permalinks postname media Lib. add new upload paysave pic make empty page   with template-casino in -child make page4todo in spin activate theme elementor-child plugin qw_casin245'; /**  ... permalinks postname media Lib. add new upload paysave pic make empty page   with template-casino in -child make page6todo in spin activate theme elementor-child plugin qw_casino  .. permalinks postname media Lib.add new upload paysave pic  make empty501'; 
                    /** mist max str len 501  in RFC3447 can operate on messages of length up to k - 11 octets (k is the octet length of the RSA modulus) so if you are using 2048-bit RSA key then maximum length of the plain data to be encrypted is 245 bytes.  /***/
            
                    echo 'str len : ', strlen($data);
            
                    $openssl_args = array(
                        "config" => $openssl_cnf_path[$try],
                        "digest_alg" => "sha512",
                        //"private_key_bits" => 4096,
                        "private_key_bits" => 2048,
                        "private_key_type" => OPENSSL_KEYTYPE_RSA,
                        "try_path_ar" => $openssl_cnf_path,
                        "data" => $data,
                        );
            
            
            
                    // Example
                    $res = testOpenSSL($openssl_args);
                    if ($res === FALSE)
                    {
                        echo "<h4 style='background-color: red;'>Fail</h4>";
                    } else {
                        echo '<h3 style=\'background-color: green; color:white;\'>with $try= '.$try.' decrypted ok: '.$res['decr'].'</h3>';
                    }
            
                            //////////////////////////////////////////
                            //
                            echo '<br>vardump res <br>';  var_dump($res);   
                            echo '<br>======================<br>';      
            
                    $privKey=$res['priv_key'];
                    $pubKey =$res['pub_key'];
                    file_put_contents('pri_key.txt',$privKey);
                    file_put_contents('priv_key.txt',$privKey);
                    file_put_contents('pub_key.txt',$pubKey);
            
            
                    echo '<br><br><pre>';
            
            
                    /* Encrypt the data using the public key
                     * The encrypted data is stored in $encrypted */
                    openssl_public_encrypt($data, $encrypted, $pubKey);
                            echo '<br>public encrypt: '; var_dump( base64_encode($encrypted));
            
            
                    /* Decrypt the data using the private key and store the
                     * result in $decrypted. */
                    openssl_private_decrypt($encrypted, $decrypted, $privKey);
                            echo ' private decrypt: ', $decrypted;      
            
            
            
                    // inverse testOpenSSL
                    openssl_private_encrypt($data, $encrypted, $privKey);
                            echo '<br><br> invers<br>pri encrypt: '; var_dump( base64_encode($encrypted));
            
                    openssl_public_decrypt($encrypted, $decrypted, $pubKey);
                            echo ' pub decrypt: ', $decrypted , '<br>'; 
            

            【讨论】:

            • 在我的情况下,在 windows xampp 中,最重要的是找到正确的 openssl.cnf 并放入 arg 数组
            【解决方案9】:

            我可以建议使用Virtual Box,创建一个虚拟机并安装 LAMP 堆栈。这会给你一个“更真实”的环境。除了故障排除 OpenSSL 在 Linux 上更容易。

            话虽如此,我相信您的问题是您找不到插件文件本身。确保它位于正确的路径并存在于您的计算机上,并且 Apache 运行的进程有权读取它。

            【讨论】:

              猜你喜欢
              • 2012-03-03
              • 2016-04-04
              • 2014-10-08
              • 2011-05-05
              • 2014-07-08
              • 1970-01-01
              • 2016-02-26
              • 1970-01-01
              相关资源
              最近更新 更多