52

问题: 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
  • %小路% E:\wamp\php
  • 重新启动
  • phpinfo:
    ----OpenSSL 支持已启用
    ----OpenSSL 库版本 OpenSSL 1.0.1e 2013 年 2 月 11 日
    ----OpenSSL 标头版本 OpenSSL 0.9.8y 2013 年 2 月 5 日
  • 有和没有指定配置configargs
  • <Directory E:\wamp\php\extras>在 apache 配置中指定和不指定
  • 复制openssl.cnf到 virtualhost public_html,指向那个并且仍然得到相同的错误
  • 没有记录错误日志
  • 研究:过去两天我一直在研究这个,很惊讶没有更多的信息,所以我在这里发帖。似乎是 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,我现在可以看到 open_ssl 错误使用openssl_error_string
  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 变量或在脚本执行期间,它都会不断出错,提示找不到文件。我能够通过在数组中传入config参数来解决它。这是一个测试能否成功使用 OpenSSL 的函数:config_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>";
    }
4

10 回答 10

9

下面的代码按预期工作。但是,如果您openssl_error_string()在 openssl 方法之后运行,它会显示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;
?>
于 2013-03-26T20:36:41.963 回答
5

这里有几件事:

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

还可以尝试与标头版本相匹配的openssl版本0.9.8y 5 Feb 2013下载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");
于 2013-07-01T16:36:30.133 回答
4

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

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

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

putenv("OPENSSL_CONF=C:\Program Files (x86)\Ampps\php\extras\openssl.cnf");
于 2013-10-20T10:50:34.243 回答
3

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

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

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

于 2015-12-12T11:42:04.357 回答
2

清洁解决方案:

  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 文件 - 它可以开箱即用。但是,如果您想微调设置,您可以。

于 2016-08-09T04:03:19.977 回答
1

您是否通过此方法安装了 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 打印的命令列表,您就知道您的安装已正确完成。

于 2013-06-07T17:41:09.987 回答
0

就我而言,将文件复制到 c:\windows\system32 帮助了我

libeay32.dll、ssleay32.dll

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

于 2014-10-14T18:07:56.340 回答
0

我对 XAMPP 也有类似的问题。我发现OPENSSL_CONFin[xampp_dir]\apache\conf\extra\httpd-xampp.conf被错误地设置为[xampp_dir]/apache/bin/openssl.cnf. 修复后就可以[xampp_dir]/apache/conf/openssl.cnf了。

于 2022-02-16T10:29:34.113 回答
0
<?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>'; 
于 2020-02-27T16:42:47.827 回答
-1

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

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

于 2013-06-19T21:00:50.010 回答