OpenSSL使用小结

引言

  互联网的发展史上,安全性一直是开发者们相当重视的一个主题,为了实现数据传输安全,我们需要保证:数据来源(非伪造请求)、数据完整性(没有被人修改过)、数据私密性(密文,无法直接读取)等。虽然现在已经有SSL/TLS协议实现的HTTPS协议,但是因在客户端上依赖浏览器的正确实现,而且效率又很低,所以一般的敏感数据(如交易支付信息等)还是需要我们使用加密方法来手动加密。


加密基础

学习如何使用加密之前,我们需要了解一些加密相关的基础知识。

加密算法一般分为两种:对称加密算法和非对称加密算法。

对称加密

对称加密算法是消息发送者和接收者使用同一个密匙,发送者使用密匙加密了文件,接收者使用同样的密匙解密,获取信息。常见的对称加密算法有:DES/3DES/AES.

对称加密算法的特点有:速度快,加密前后文件大小变化不大,但是密匙的保管是个大问题,因为消息发送方和接收方任意一方的密匙丢失,都会导致信息传输变得不安全。

非对称加密

与对称加密相对的是非对称加密,非对称加密的核心思想是使用一对相对的密匙,分为公匙和私匙,私匙自己安全保存,而将公匙公开。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。发送数据前只需要使用接收方的公匙加密就行了。常见的非对称加密算法有RSA/DSA:

非对称加密虽然没有密匙保存问题,但其计算量大,加密速度很慢,有时候我们还需要对大块数据进行分块加密。

数字签名

为了保证数据的完整性,还需要通过散列函数计算得到一个散列值,这个散列值被称为数字签名。其特点有:

  • 无论原始数据是多大,结果的长度相同的;
  • 输入一样,输出也相同;
  • 对输入的微小改变,会使结果产生很大的变化;
  • 加密过程不可逆,无法通过散列值得到原来的数据;

常见的数字签名算法有md5,hash1等算法。


 

PHP的openssl扩展

首先安装 openssl,开启php的 php_openssl 扩展;openssl扩展使用openssl加密扩展包,封装了多个用于加密解密相关的PHP函数,极大地方便了对数据的加密解密。

对称加密相关

string openssl_encrypt string $data , string $method , string $key [, int $options = 0 [, string $iv = "" [, string&$tag = NULL [, string $aad = "" [, int $tag_length = 16 ]]]]] )

以指定的方式和 key 加密数据,返回原始或 base64 编码后的字符串或者在失败时返回 FALSE

data     待加密的明文信息数据

method    加密算法方式。openssl_get_cipher_methods() 可获取有效密码方式列表。

options          是以下标记的按位或: OPENSSL_RAW_DATA 、 OPENSSL_ZERO_PADDING

iv      非 NULL 的初始化向量,在使用aes加密时,密钥长度128:iv 16bit;192:iv 24bit;256:iv 32bit

tag      使用 AEAD 密码模式(GCM 或 CCM)时传引用的验证标签。

aad       附加的验证数据。

tag_length  验证 tag 的长度。GCM 模式时,它的范围是 4 到 16。

 string openssl_decrypt ( string $data , string $method , string $key [, int $options = 0 [, string $iv = "" [, string $tag = "" [, string $aad = "" ]]]] )

实例:

1 $encryptString = '那数十位天关境后期的骄子,皆是暴喝出声,下一瞬间';
2 echo '<pre>';
3 $ss = openssl_encrypt($encryptString, 'AES-128-CBC', '1234567887654321',0,'1234567812345678');
4 #3d/Gei0wiCwSjj3pmS5DF0ZHOesVqLglnAcr3l8+Hjy84/iEyGOIYaTBOgwnth+BsjtOvv1F//dtfRJL71tsv2sxu1OiPSgTTS3/o1mxXCI=
5 
6 echo $ss,PHP_EOL;
7 
8 echo (openssl_decrypt($ss, 'AES-128-CBC', '1234567887654321',0,'1234567812345678'));
9 #那数十位天关境后期的骄子,皆是暴喝出声,下一瞬间

 

非对称加密相关

生成 RSA 密钥对

命令:

openssl  genrsa [-out filename] [-passout arg] [-f4] [-3] [-rand file(s)] [-engine id] [-des|-des3|-idea] [numbits]

实例:

#简化方式
#生成私钥
openssl genrsa -out rsa_private_key.pem 1024

#将原始私钥转换为pkcs8格式
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem

#根据私钥生成公钥
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

#----------------------------------------------------------------------------------
#生成1024位rsa私钥,使用3des算法加密它(不加密使用明文保存密钥),口令为trousers
#输出到文件 rsaprivatekey.pem
openssl genrsa -out rsaprivatekey.pem -passout pass:trousers -des3 1024

#使用私钥生成公钥,生成的公钥输出到rsapublickey.pem
openssl rsa -in rsaprivatekey.pem -passin pass:trousers -pubout -out rsapublickey.prm

 实例:简单的加密解密类

 1 <?php
 2 
 3 class RsaCrypt {
 4 
 5     const PRIVATE_KEY_FILE_PATH = 'C:/Users/lenovo/rsa_private_key.pem';
 6     const PUBLIC_KEY_FILE_PATH = 'C:/Users/lenovo/ras_public_key.pem';
 7 
 8    
 9     public static function encode($orignData) 
10     {
11         //密钥文件的路径
12         $privateKeyFilePath = self::PRIVATE_KEY_FILE_PATH;
13         extension_loaded('openssl') or die('php需要openssl扩展支持');
14         (file_exists($privateKeyFilePath)) or die('密钥的文件路径不正确');
15         //生成Resource类型的密钥,如果密钥文件内容被破坏,openssl_pkey_get_private函数返回false
16         $privateKey = openssl_pkey_get_private(file_get_contents($privateKeyFilePath));
17      
18         ($privateKey) or die('密钥不可用');
19         //加密以后的数据,用于在网路上传输
20         $encryptData = '';
21         ///////////////////////////////用私钥加密////////////////////////
22         if (openssl_private_encrypt($orignData, $encryptData, $privateKey)) {
23             return base64_encode($encryptData);
24         } else {
25             die('加密失败');
26         }
27     }
28    
29     public static function decode($encryptData) 
30     {
31         //公钥文件的路径
32         $publicKeyFilePath = self::PUBLIC_KEY_FILE_PATH;
33         extension_loaded('openssl') or die('php需要openssl扩展支持');
34         (file_exists($publicKeyFilePath)) or die('公钥的文件路径不正确');
35         //生成Resource类型的公钥,如果公钥文件内容被破坏,openssl_pkey_get_public函数返回false
36         $publicKey = openssl_pkey_get_public(file_get_contents($publicKeyFilePath));
37         ($publicKey) or die('公钥不可用');
38         //解密以后的数据
39         $decryptData = '';
40         ///////////////////////////////用公钥解密////////////////////////
41         if (openssl_public_decrypt(base64_decode($encryptData), $decryptData, $publicKey)) {
42             return $decryptData;
43         } else {
44             die('解密失败');
45         }
46     }
47 }
48 
49 $rsa = new RsaCrypt();
50 
51 $en = $rsa->encode('你好');
52 $de = $rsa->decode($en);
53 
54 echo $en;
55 echo $de;

 

OpenSSL 命令总览

version    用于查看版本信息

enc          用于加解密

ciphers    列出加密套件

genrsa    用于生成私钥

rsa          RSA密钥管理(例如:从私钥中提取公钥)

req          生成证书签名请求(CSR)

crl           证书吊销列表(CRL)管理

ca           CA管理(例如对证书进行签名)

dgst        生成信息摘要

rsautl       用于完成RSA签名、验证、加密和解密功能

passwd    生成散列密码

rand        生成伪随机数

speed      用于测试加解密速度                    

s_client    通用的SSL/TLS客户端测试工具

X509         X.509证书管理

verify        X.509证书验证

pkcs7        PKCS#7协议数据管理

pkcs8        PKCS#8协议数据管理

pkcs12       PKCS#12协议数据管理

详细参考 http://blog.csdn.net/as3luyuan123/article/list/3

posted @ 2017-11-27 10:40  骑着蜗牛闯世界  阅读(2255)  评论(0编辑  收藏  举报