• php中ssl开发的若干问题


    最近利用php开发ssl的相关功能,由于第一次做相关的事情,遇到了很多问题,庆幸的是最终都顺利解决了。不过相关的资料很少,都是综合了国内外的相关信息才解决的。现在整理一下,方便后来者遇到问题时解决。
    1. 首先扫下盲,什么是数字签名
    推荐一个通俗易懂的教程:中文版 英文版
    其实整个过程就是:
    数据->hash-》摘要-》私钥对摘要加密-》数字签名
     |                                      |
    hash                                公钥解密
     |                                      |
    摘要-------------是否相等--------------摘要
    2. Fatal error: Call to undefined function openssl_pkey_get_public() in 。。。
    这个问题主要是因为php.ini中,extension=php_openssl.dll的选项没有打开,把分号去掉,重启apache即可。
    3. 用php的openssl_verify函数无法验证由其他函数库生成的签名
    比如用c++的函数库生成了一个签名,将其发送给服务器端验签,用php的openssl_verify函数,总是无法通过,并且有以下错误提示:
    error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
    error:0D068066:asn1 encoding routines:ASN1_CHECK_TLEN:bad object header
    error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error
    主要原因是openssl_verify函数是对上面讲的验签过程的高度封装,包括公钥解密,数据校验,比较摘要等过程。这个函数的特别之处是,它需要这个签名必须包含hash头,而有些函数生成的签名是不包含这个hash头的,所以总是有参数错误。
    解决的办法就是自己实现这个verify函数。简单的过程如下:
    $sha1 = sha1($data, true);
    $sign = base64_decode($sign);
    $deco = '';
    $pubkid = openssl_pkey_get_public($cert);
    openssl_public_decrypt($sign, $deco, $pubkid);
    最后比较$sha1和$deco是否相等。
    4.Warning: openssl_verify(): Don't know how to get public key from this private key in。。。
    Warning: openssl_verify(): supplied key param cannot be coerced into a public key in。。。
    Warning: openssl_public_decrypt(): Don't know how to get public key from this private key in。。。
    Warning: openssl_public_decrypt(): key parameter is not a valid public key in 。。。
    明明各种配置都正确,为什么会有这样的警告?而且函数无法得到正确结果。
    这个原因是apache和php的openssl版本不一致。apache和php的openssl功能都依赖于libeay32.dll和 ssleay32.dll这两个库,但是这两个文件并非被apache和php共用,而是各用各的。比如apache中这两个文件一般在bin目录,而 php中就在php目录中。仔细看他们的信息会发现,这些文件都有版本信息,关键就是这个版本不一致导致。有人说将php中的这两个文件直接复制到 apache的bin目录中可以解决问题,但是不推荐这样做,因为也许在其他地方会出现错误。如果是自己配置,就下载apache和php中这两个文件版 本一致的。如果不想自己配置,可以使用xampp1.7.1版本。下载地址
    5.最后说一下https的配置 (转自这里,并做了适当修改)
    SSL: SSl是为Http传输提供安全的协议,通过证书认证来确保客户端和网站服务器之间的数据是安全。也就是说在SSL下http传输是安全的,我们成为 https. 
    配置过程如下: 
    步骤一:安装apache,使其支持SSL,并安装php 
    1.安装配有SSL模块的apache,比如apache_2.2.8-win32-x86-openssl-0.9.8g 
    2.配置apache以支持SSL:打开apache的配置文件conf/httpd.conf 
    1)LoadModule ssl_module modules/mod_ssl.so、Include conf/extra/httpd-ssl.conf 
    去掉两行前面的# 
    2)注意修改httpd-ssl.conf 文件里的两个字段: 
    SSLCertificateFile "C:/Apache2.2/conf/server.crt" 
    SSLCertificateKeyFile "C:/Apache2.2/conf/server.key" 
    3.安装php,整合apache和Php(略) 
    为下面你所生成的证书和密钥地址。 
    步骤二:为网站服务器生成证书及私钥文件 
    1. 生成服务器的私钥
    进入命令行: 
    D:localapache2inopenssl genrsa -out server.key 1024 
    在当前目录下生成了一个server.key生成签署申请 
    2. 生成签署申请 
    D:localapache2in>openssl req -new –out server.csr -key server.key -config..confopenssl.cnf 
    此时生成签署文件server.csr. 
    步骤三:通过CA为网站服务器签署证书
    1.生成CA私钥 
    D:localapache2inopenssl genrsa -out ca.key 1024 
    多出ca.key文件 
    2.利用CA的私钥产生CA的自签署证书 
    D:localapache2inopenssl req -new -x509 -days 365 -key ca.key -out ca.crt -config ..confopenssl.cnf 
    此时需要输入一些信息,注意Common Name为服务器域名,如果在本机,为本机IP。
    3.CA为网站服务器签署证书 
    D:localapache2inopenssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key -config ..confopenssl.cnf
    但,此时会报错,于是在在当前目录创建demoCA,里面创建以下文件,index.txt,serial,serial中内容为01,其他为空,以及文件夹 newcert.再执行一遍,即可生成server.crt文件 
    步骤四:然后将 server.crt,server.key复制到apache的conf文件夹下,重启apache
    若是使用了xampp,其中自带了证书和私钥,不用自己配置,直接支持https。只需修改http-ssl.conf中的documentroot字段,想用https访问哪个目录就改为哪个。
    若以http访问,则http.conf中documentroot指向哪里,就访问哪里;若以https访问,则http-ssl.conf中的documentroot指向哪里就访问哪里。
  • 相关阅读:
    postman断言作用及怎么使用
    深入理解Spring MVC 思想
    serialVersionUID的作用以及如何用idea自动生成实体类的serialVersionUID
    HttpClient通过Post方式发送Json数据
    HttpClient获取Cookie的两种方式
    HTTPclient cookie的获取与设置
    【BIEE】11_根据显示指标展示不同报表
    【Excle】科学计数法快速还原
    【BIEE】10_资料库查看数据报错
    【BIEE】09_BIEE控制台乱码问题解决
  • 原文地址:https://www.cnblogs.com/baocheng/p/6071293.html
Copyright © 2020-2023  润新知