zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    一个、说到所有的扩展指标
    时序图、流程图
    流程图总结
    UML活动图与流程图的区别
    类图与对象图
    app的描述-软件的描述
    UML的目标
    软件建模的用途
    Android中如何使用Intent在Activity之间传递对象[使用Serializable或者Parcelable]
    Serializable 和 Parcelable 区别
  • 原文地址:https://www.cnblogs.com/jinxiblog/p/7903033.html
Copyright © 2011-2022 走看看