Openssl 生成rsa私钥、公钥和证书

  1. SSL
  2. OpenSSL
  3. openssl 的编译安装
    1. 快速安装
    2. 产生私钥
    3. 产生公钥
  4. 生成证书
  5. 生成待签名的字符串
  6. RSA签名
    1. 请求时签名
    2. 通知返回时验证签名
  7. 更多

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, 请确保你已安装以下组件:

快速安装

$ ./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' => '2015012041879426',
'reason' => '商品质量问题',
'trans_fee' => '1000',
'payee_account' => 'fengzbao@qq.com',
'payee_name' => '冯宗宝',
);

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;
}

注意:

RSA签名

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

请求时签名

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

通知返回时验证签名

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

更多

本文只是在做支付过程中的一个指导文件,openssl还可以对文件生成信息摘要等,大家可以参考下面的两篇文章获取更多信息:

script>