自从老罗赞助了openssl以及心脏出血事件的新闻,得以了解了openssl。那么什么是openssl呢?下面摘自官网:
The OpenSSL Project is a collaborative effort to develop a robust, commercial-grade, full-featured, and Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS) protocols as well as a full-strength general purpose cryptography library. The project is managed by a worldwide community of volunteers that use the Internet to communicate, plan, and develop the OpenSSL toolkit and its related documentation.
简单地说,就是用来保证通信安全的。那么我们常用的php怎么使用呢?在网上找了一下,方法是在php.ini文件中添加extension=php_openssl.dll这个模块,然后将php_openssl.dll, ssleay32.dll, libeay32.dll 3个文件拷贝到 WINDOWS\system32\ 文件夹下。其实就是将这些dll放入环境变量path中去。
但是我一般都是使用集成的服务器套件的,比如phpnow,但是缺点是其没有默认打开这个模块,导致我按照这个步骤做依然不行;然后我在使用xampp的时候,就发现其是默认打开了Openssl的,所以相对是比较方便的。
然后当环境搭建好了,我们肯定就会迫不及待地去测试了。这里我给出网上找的两个例子:
1.使用了openssl_encrypt()这个函数,然后会在目录中产生一个加密后的文件,要解密这个文件,这个例子中使用的是命令行的方法。
1 <?php 2 3 function strtohex($x) 4 { 5 $s=''; 6 foreach (str_split($x) as $c) $s.=sprintf("%02X",ord($c)); 7 return($s); 8 } 9 10 $source = 'It works !'; 11 12 $iv = "1234567812345678"; 13 $pass = '1234567812345678'; 14 $method = 'aes-128-cbc'; 15 16 echo "<br>iv in hex to use: ".strtohex ($iv); 17 echo "<br>key in hex to use: ".strtohex ($pass); 18 echo "<br>"; 19 20 file_put_contents ('./file.encrypted',openssl_encrypt ($source, $method, $pass, true, $iv)); 21 22 $exec = "openssl enc -".$method." -d -in file.encrypted -nosalt -nopad -K ".strtohex($pass)." -iv ".strtohex($iv); 23 24 echo 'executing: '.$exec."<br><br>"; 25 echo exec ($exec); 26 echo "<br>"; 27 28 ?>
2.第二个例子使用openssl_pkey_new()这个函数产生了一个密钥对,然后利用公钥加密和私钥解密举例。
<?php if (isset($_SERVER['HTTPS']) ) { echo "SECURE: This page is being accessed through a secure connection.<br><br>"; } else { echo "UNSECURE: This page is being access through an unsecure connection.<br><br>"; } // Create the keypair $res=openssl_pkey_new(); // Get private key openssl_pkey_export($res, $privatekey); // Get public key $publickey=openssl_pkey_get_details($res); $publickey=$publickey["key"]; echo "Private Key:<BR>$privatekey<br><br>Public Key:<BR>$publickey<BR><BR>"; $cleartext = '1234 5678 9012 3456'; echo "Clear text:<br>$cleartext<BR><BR>"; openssl_public_encrypt($cleartext, $crypttext, $publickey); echo "Crypt text:<br>$crypttext<BR><BR>"; openssl_private_decrypt($crypttext, $decrypted, $privatekey); echo "Decrypted text:<BR>$decrypted<br><br>"; ?>
但是这个例子我在机子上确没有正确地运行。首先是使用https协议访问就会出问题,第二个是openssl_pkey_new()这个函数没有办法产生密钥对。
使用openssl_error_string()查看出错的问题,error:02001003:system library:fopen:No such process,然后我将xampp/php这个路径加入到path环境变量中去。然后再查看,问题是:error:2006D080:BIO routines:BIO_new_file:no such file。
好像是openssl不能找到openssl.cnf这个文件。然后查看文档:
PHP will search for the openssl.cnf using the following logic:
很清楚地说明了php寻找openssl.cnf有三种方式。
添加环境变量,右击我的电脑属性里就可以,然后我试了,没有成功:(看到计算机里众多的dll和openssl.cnf,我就想放弃了。如果有人成功了请告诉我。
然后看到官方文档最后一句话:Note that it is possible to override the default path from the script using the configargs
of the functions that require a configuration file.
于是我在范例前面添加一个config变量,以后用的所有openssl函数里都添加$config来设置,这样居然成功了!!!!
<?php //cnf存放路径 $opensslConfigPath = "D:/xampp/apache/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); if (empty($res)) {return false;} openssl_pkey_export($res, $privKey, NULL, $config); $pubKey = openssl_pkey_get_details($res); if ($pubKey === FALSE){return false;} $pubKey = $pubKey["key"]; $data = '1234 5678 9012'; echo '原文:'.$data; // 加密 if ($res === FALSE){return false;} openssl_public_encrypt($data, $encrypted, $pubKey); // 解密 $res = openssl_private_decrypt($encrypted, $decrypted, $privKey); if ($res === FALSE){return false;} else echo '<br>解密后:'.$decrypted;
大家可以复制过去看看运行结果。
至此终于顺利试用了openssl:)