zoukankan      html  css  js  c++  java
  • 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指向哪里就访问哪里。
  • 相关阅读:
    day01--计算机硬件基础笔记
    22 Jun 18 Django,ORM
    21 Jun 18 Django,ORM
    20 Jun 18 复习, mysql
    20 Jun 18 Django,ORM
    19 Jun 18 复习, 正则表达式
    19 Jun 18 Django
    15 Jun 18 复习, shutil模块
    15 Jun 18 Django
    14 Jun 18 复习, form表单
  • 原文地址:https://www.cnblogs.com/baocheng/p/6071293.html
Copyright © 2011-2022 走看看