• Openssl 生成rsa私钥、公钥和证书
  • 发布于 1周前
  • 37 热度
    0 评论
SSL
SSL 是一个缩写,代表的是 Secure Sockets Layer。它是支持在 Internet 上进行安全通信的 标准,并且将数据密码术集成到了协议之中。数据在离开您的计算机之前就已经被加密,然后只有 到达它预定的目标后才被解密。证书和密码学算法支持了这一切的运转,使用 OpenSSL,您将 有机会切身体会它们。
理论上,如果加密的数据在到达目标之前被截取或窃听,那些数据是不可能被破解的。不过, 由于计算机的变化一年比一年快,而且密码翻译方法有了新的发展,因此,SSL 中使用的加密协议 被破解的可能性也在增大。
可以将 SSL 和安全连接用于 Internet 上任何类型的协议,不管是 HTTP、POP3,还是 FTP。还可以用 SSL 来保护 Telnet 会话。虽然可以用 SSL 保护任何连接,但是不必对每一类连接都使用 SSL。 如果连接传输敏感信息,则应使用 SSL。

OpenSSL
OpenSSL 不仅仅是 SSL。它可以实现消息摘要、文件的加密和解密、数字证书、数字签名 和随机数字。关于 OpenSSL 库的内容非常多,远不是一篇文章可以容纳的。
OpenSSL 不只是 API,它还是一个命令行工具。命令行工具可以完成与 API 同样的工作, 而且更进一步,可以测试 SSL 服务器和客户机。它还让开发人员对 OpenSSL 的能力有一个 认识。要获得关于如何使用 OpenSSL 命令行工具的资料,请参阅 官方手册。

openssl 的编译安装

下载https://www.openssl.org/source/

安装 OpenSSL, 请确保你已安装以下组件:

make
Perl 5
an ANSI C compiler
a development environment in form of development libraries and C
header files

a supported Unix operating system


快速安装
$ ./config
$ make
$ make test
$ make install
更多的安装细节可以参考安装包中的INSTALL文件:https://github.com/openssl/openssl/blob/master/INSTALL

产生私钥
➜  ~  openssl
OpenSSL> genrsa -out rsa_private_key.pem 1024              
Generating RSA private key, 1024 bit long modulus
..........++++++
...++++++
e is 65537 (0x10001)
OpenSSL>
➜  ~  vim rsa_private_key.pem 
----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDLAwyua/Mhu4Ik8a2iLst0yWijyyDeHsuTEM9/X/IhAtlxHJ7w
GmO5UmD0rSGv5rGDlu5n/jo8p35WLbOGTocs9RlOV5wS69rxtiO0CHHSdOi+jh1r
+9mDiPmnQQ2sOl6KFsvGwRB3UaCc6LgqDqsg89/f4IkrLLas3nPRa989RQIDAQAB
AoGALjLZde/2+lwzd7jP7LJ9dmxHNc8KAcI8TZFrxu7MqRp+5TDAMp+uxgOrMMMd
gWwcRXfZdSzzj84GABKSYiQIupg7V6rk/XgmIQAiBjWEvyzpwp71IRE9dzhkL5Qc
WF/PymajQ766vI1FhhLdU85Rc0Gly5ZawsfQGDBJ/s6AWMECQQD47D4gPA/Pnzpx
5VnMJpgLLqA7E5oOBiD0EINUZ0iYPMu/EYazUTAcLoRitUQorm16aP7IjaUvymHA
9HfDYsXpAkEA0MimPCuD3Pg8xaaSrqGXSCufOMezIOZcnFYSCIcAy0p0mBoySZON
ypvjB8ojhvCONRhQFJy35OlFuAOsl162/QJBAMNYalzTpbjTBYOycGkU9Ib5/Ua/
WEufJadDejz3nPHT7DUy5Nm+YhoLq1rnU+j1EfdZhHERL8w0b8iEUaRk1FkCQBEG
S4fchIQgOdRkINHcm1lnNTSMFC86mZKl8hJ/77CkAZ3lhPQ68/TxgTHBaeQ2+WGa
+ey0Wspvux+mLQyqzIECQQDEL+4/UFI/wKAsO41k8wibzZ8/Rm3BQTwV0i5tzxHO
9N5jIHkZa5AIVhq2qNBD+ev8gNp9MbipYUhduHrudLdS

-----END RSA PRIVATE KEY-----


产生公钥
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
writing RSA key

➜  ~  vim rsa_public_key.pem 

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLAwyua/Mhu4Ik8a2iLst0yWij
yyDeHsuTEM9/X/IhAtlxHJ7wGmO5UmD0rSGv5rGDlu5n/jo8p35WLbOGTocs9RlO
V5wS69rxtiO0CHHSdOi+jh1r+9mDiPmnQQ2sOl6KFsvGwRB3UaCc6LgqDqsg89/f
4IkrLLas3nPRa989RQIDAQAB

-----END PUBLIC KEY-----


生成证书
➜  ~  openssl req -new -key rsa_private_key.pem -out zongbao.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:cn
State or Province Name (full name) [Some-State]:beijing
Locality Name (eg, city) []:bj
Organization Name (eg, company) [Internet Widgits Pty Ltd]:jinritemai
Organizational Unit Name (eg, section) []:jrtm
Common Name (e.g. server FQDN or YOUR name) []:fengzbao
Email Address []:fengzbao@qq.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:1q2w3e4r
An optional company name []:jinritemai

➜  ~


生成待签名的字符串

要参与签名的参数
在请求参数列表中,除去 sign、sign_type 两个参数外,其他需要使用到的参数皆是要签名的参数。(个别接口中参数 sign_type 也需要参与签名。)在通知返回参数列表中,除去 sign、sign_type 两个参数外,凡是通知返回回来的参数皆是要签名的参数

根据支付宝的要求,数组需要完成以下重组:

对数组里的每一个值从 a 到 z 的顺序排序,若遇到相同首字母,则看第二个字母,以此类推。排序完成之后,再把所有数组值以“&”字符连接起来,
public function sign($data)
{
 $array = array (
     'out_trade_no' => '15002420575997',
     'trade_no' => '2010012041879426',
     'reason' => 'www.mylanqiu.com可购买的余额不足',
     'trans_fee' => '1000',
     'payee_account' => 'service@mylanqiu.com',
     'payee_name' => 'www.mylanqiu.com',
 );
 ksort($array);
 $message = '';
 foreach($array as $key=>$value){
     $message .= $key."=".$value."&";
 }
 $message = substr($message, 0, -1);
 $pric_key_id = openssl_get_privatekey($this->private_key);

    openssl_sign($this->message, $signgure, $pric_key_id);
    openssl_free_key($pric_key_id);
 
}    
public function verify($data)
{
    $sign = $data['tt_sign'];
    unset($data['tt_sign']);
    unset($data['tt_sign_type']);
    ksort($data);

    $message = '';
    foreach ($data as $key => $value) {
        $message .= $key . '=' . $value . '&';
    }
    $message = substr($message, 0, -1);
    $publicKey = ;
    $publicKeyId = openssl_pkey_get_public($publicKey);
    $result = openssl_verify($message, base64_decode($sign), $publicKeyId);
    openssl_free_key($publicKeyId);
    return $result;
}
注意:
没有值的参数无需传递,也无需包含到待签名数据中;根据 HTTP 协议要求,传递参数的值中如果存在特殊字符(如:&、@等),那么该值需要做 URL Encoding,这样请求接收方才能接收到正确的参数值。这种情况下,待签名数据应该是原生值而不是 encoding 之后的值。例如:调用某接口需要对请求参数 email 进行数字签名,那么待签名数据应该是

email=test@mylanqiu.com,而不是 email=test%40mylanqiu.com。


RSA签名
在 DSA 或 RSA 的签名时,需要私钥和公钥一起参与签名。私钥与公钥皆是客户通过 OPENSSL 来生成得出的。客户把生成出的公钥与支付宝技术人员配置好的支付宝公钥做交换。因此,在签名时,客户要用到的是客户的私钥及支付宝的公钥。

请求时签名
当拿到请求时的待签名字符串后,把待签名字符串与客户的私钥一同放入 DSA 或RSA 的签名函数中进行签名运算,从而得到签名结果字符串。

通知返回时验证签名
当获得到通知返回时的待签名字符串后,把待签名字符串、支付宝提供的公钥、支付宝通知返回参数中的参数 sign 的值三者一同放入 DSA 或 RSA 的签名函数中进行非对称的签名运算,来判断签名是否验证通过。
用户评论