SSL生成和验证实战案例

【今日推荐】:为什么一到面试就懵逼!>>> hot3.png

  • 目录
  • 1. 前言
  • 2. 生成签名函数openssl_sign()
  • 2.1 概念
  • 2.2 格式
  • 3. 验证签名函数openssl_verify()
  • 3.1 概念
  • 3.2 格式
  • 4. 生成秘钥
  • 5. 错误处理
  • 5.1错误提示
  • 5.2错误处理
  • 6. 验证秘钥
  • 7. 总结

1.前言

在进行跨域访问验证时,会经常用到SSL作为密钥,下面我们一起总结一下。

代码分享:https://github.com/mtdgclub/opensslSign

2.生成签名函数openssl_sign()

2.1 openssl_sign概念

openssl_sign 是用来生成签名的,data通过使用与之关联的私钥生成加密数字签名来计算指定的签名 priv_key_id。请注意,数据本身未加密。

2.2 openssl_sign格式

bool openssl_sign ($data,&$signature,$priv_key_id,$signature_alg)

变量名

类型

参数

其他

data

String

您要签名的数据字符串

 

signature

string

返回签名 signature

 

priv_key_id

mixed 

返回的私钥

 

signature_alg

mixed=OPENSSL_ALGO_SHA1

签名算法

 

(非必填)

返回值

Bool

TRUE/FALSE

 

上面这段好像有点难以理解,下面通俗点解释:

private static function sign($data){
        $pk = self::$private_key;
        openssl_sign($data, $sign, $pk);
        $sign = base64_encode($sign);
        return $sign;
    }

3.验证签名函数openssl_verify()

3.1 openssl_sign概念

openssl_sign 是用来验证签名的, 使用与之关联的公钥 验证signature指定的内容 是否正确 。这必须是与用于签名的私钥对应的公钥。

3.2 openssl_sign格式

bool openssl_verify ($data,&$signature,$priv_key_id,$signature_alg)

变量名

类型

参数

其他

data

String

用于先前生成签名的数据字符串

 

signature

string

原始二进制字符串,由openssl_sign()或类似方法生成

 

priv_key_id

mixed 

公钥

 

signature_alg

mixed=OPENSSL_ALGO_SHA1

签名算法

(非必填)

返回值

Bool

签名正确返回1/不正确返回0/出错返回-1

 

4.生成秘钥

<?php
//要签名的数据
$data  =  'my data' ;
//创建新的私钥和公钥
$new_key_pair  =  openssl_pkey_new (array(
    "private_key_bits"  =>  2048 ,
    "private_key_type"  =>  OPENSSL_KEYTYPE_RSA ,
));
openssl_pkey_export ( $new_key_pair ,  $private_key_pem );
$details  =  openssl_pkey_get_details ( $new_key_pair );
$public_key_pem  =  $details [ 'key' ];
//create signature 创建签名
openssl_sign ( $data ,  $signature ,  $private_key_pem ,  OPENSSL_ALGO_SHA256 );
//save for later 保存供以后使用
file_put_contents ( 'private_key.pem' ,  $private_key_pem );//私钥
file_put_contents ( 'public_key.pem' ,  $public_key_pem );//公钥
file_put_contents ( 'signature.dat' ,  $signature );//签名
//verify signature 验证签名
$r  =  openssl_verify ( $data ,  $signature ,  $public_key_pem ,  "sha256WithRSAEncryption" );
if ( $r  ==  1 ) {
    echo  "valid" ;
} elseif ( $r  ==  0 ) {
    echo  "invalid" ;
} else {
    echo  "error: " . openssl_error_string ();
}

数字签名说明:

1)使用完全加密的数据进行传输的好处是更加安全,但是计算更加复杂,需要传输的数据也更多;
2)更常用的方式只是对要传输的数据做一个数字签名,在接收端对接收到的数据进行一个签名运算,只要客户端计算的签名和接受的的签名一样就可以认为收到的数据没有被篡改过。
3)计算签名使用openssl提供的openssl_sign(),签名验证使用openssl_verify()

5. 错误处理

5.1错误提示

PHP生成RSA密钥提示错误“openssl_pkey_export and “cannot get key from parameter 1”

5.2错误处理

up-212f931372a43662c6ad5f4d0987ee8863c.png

找到phpinfo里面的openssl的如上图路径并建立,将apache里面的openssl.cnf复制到该路径下即可解决。

6.验证秘钥

<?php
header('content-type:text/html;charset=utf8');
//私钥
$private_key = '-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA346nvWRmWhmdpHSsai6aUfDg9SehCUsDmBNji8OXmiQJmkBO
ssN/cu3Ifap7P6sgENzZbh/SYB/+i3JeBGlQetFt+kjJQnr1lDUQlSWBBq6OyxGT
LYDw3NyFsV1BN/NdQ06HzT1k/J0AZChyLMpMR8HUWZE6stbnocdY9aDXXAILyRa6
tJ6WUwepfMUFZfQAxWkpNLVXzY+QTf95ACblqVRoqRbVNNL4AOT1FYmQyIrD9gUI
wMQaUJ+2fGJtT9m1rbLpj87BddKKw5T7TOwqwDJrEgrHQ5m3YmphAEIrM6ZreV2C
FlT4RI8kvFfivqo/TvuTO4rMITzCwvxK6+dzuwIDAQABAoIBAQCRaFVcT6hvJEgw
Bp96dRN1BqsbagpJZBxTVxEhgDfkT1pblUZa6ePE2jrU2gVOVT0HGs7l3RbV5RmI
k/vo/KMXL49MAvm9HwMKwjUl/X3d3b4NAUJsj3ia/2iKA7D+9nEL7VFRQoSj9m6h
ttkEnxRcfAtlspuuZS/GP0ZyhYpuUcMoyCXEGknvp+xCrbWPSwjZR4qrd/c5XP2H
aRn+3ZaKiZOnVR765zN+DOOBvD+AuHT0bHxg9dceir5U+cTWNQ9mopR4+lsjcxIF
BjzOFsx6nxz53Si0Lz+nKVtnUKRRTYbiXnVra3MuSVheu1MYLXDY/fGQIv0o1U8G
2s2if7NRAoGBAPBhczAwi5slugweFBvn5QC/tumvn49+A9r4eugcglDrXPbBhbcT
gzGwTogS8rT8BosowY6d4QI7sajdRtG0+Lga/plILIjif8ksJPGTnkRVFmilJN25
QSmdcU8iX60AJCpz4t6wk2rLeFfyXh+Pdi7j6/ipn9XgoW+cbODSIm7TAoGBAO4V
XEmcsNHVuX/g/QaBYEjo/kXqbnZ28/1sNAEwFZ8mI4NEah8e80lLiNyjXcGN/6UC
2UgTukkghwpKRDBNqmuOHb85Ps3Kl2WwAs2vHwdyUxbO9+z0nXBVZrE7nRUoatxy
T2fEzqWu3zVVbVdHcE5VSr5SHHbTtGYiH4P3A2Z5AoGAUBHF0rl45zcL39ltDVaT
G0rA3NpZJeztz9SQ7BwC9H1RvAf+SFtBih2WKxFUsyB39Yaf4qeIObw0k3ERk+za
JEkpoVk/LGF1+0avD6ECSPSmwDiyLQD2Saxd/+QNRo0TfuiXG2Jp2FrqPTFIVO7u
iPP2uB+YVB+85naOddzJB20CgYEAodpBoAV2q1/5OHcybB693zMN0Wf66mwZmLnb
bMdMm6Ho2I9E+Z0n1TcVdrFUxoWLOpmCLx7CMH59b0BntNLHvVCi5mG7UVmdrNKI
RV384SoWVFYlc6Aj+78DDg+xzTVp2C2Zz7iap0YHlhFaQNBfB9Gx+0qE8T8gz6H4
/NSLKjkCgYBHjrlArjQufEwC2Evz+aMpB6Ie//P7OKXVTHQZUkv5bWKCBgYbukb1
ErpDGUZqjRY0uJ3NUspcdIAYFu7vqHk7/epT1Ev6qGb6v9tkM7iudtS7LBtsfSjx
Z8G0msgfQDur9pyEVb9L3Im5K5TrzUiDZt0s1eok6WrwpiLOjNMoEw==
-----END RSA PRIVATE KEY-----';
//公钥
$public_key = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA346nvWRmWhmdpHSsai6a
UfDg9SehCUsDmBNji8OXmiQJmkBOssN/cu3Ifap7P6sgENzZbh/SYB/+i3JeBGlQ
etFt+kjJQnr1lDUQlSWBBq6OyxGTLYDw3NyFsV1BN/NdQ06HzT1k/J0AZChyLMpM
R8HUWZE6stbnocdY9aDXXAILyRa6tJ6WUwepfMUFZfQAxWkpNLVXzY+QTf95ACbl
qVRoqRbVNNL4AOT1FYmQyIrD9gUIwMQaUJ+2fGJtT9m1rbLpj87BddKKw5T7TOwq
wDJrEgrHQ5m3YmphAEIrM6ZreV2CFlT4RI8kvFfivqo/TvuTO4rMITzCwvxK6+dz
uwIDAQAB
-----END PUBLIC KEY-----';
//判断私钥是否可用
$pi_key=openssl_pkey_get_private($private_key);
//判断公钥是否可用
$pu_key=openssl_pkey_get_public($public_key);
$data="this is a test";
$encrypted = "";//存放公钥
$decrypted = "";//存放私钥
echo "------------------","私钥加密,用公钥解密:","--------------------"."<br>";
echo "source data:".$data.'<br>';
echo "加密内容:<br>";
openssl_private_encrypt($data,$encrypted,$pi_key);//私钥加密
//加密后的内容通常含有特殊字符,
//需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的
$encrypted = base64_encode($encrypted);
//输出最终私钥
echo $encrypted,'\n';
echo "<hr>";
echo "解密开始:<br>";
//私钥加密的内容通过公钥可用解密出来
openssl_public_decrypt(base64_decode($encrypted),$decrypted,$pu_key);
echo $decrypted,"\n";
echo "<br>-----------------","公钥加密,用私钥解密:","------------------"."<br>";
openssl_public_encrypt($data,$encrypted,$pu_key);//公钥加密
$encrypted = base64_encode($encrypted);
echo '加密内容:<br>',$encrypted;
echo "<hr>";
echo "解密内容:<br>";
openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key);//私钥解密
echo $decrypted,"\n";

输入结果如下图所示:

up-352f3f6b986cf0802403084fd1181c62b97.png

7.总结

SSL经常用在跨域的校验上,掌握和使用SSL将大大提高系统的安全性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值