PHP中使用RSA加密总结
2015-12-22 14:39
531 查看
数据加密方式有多种,常用的是MD5(),RSA等,对于PHP中的RSA加密算法和使用,主要有下面这些:
以上是RSA加密算法的常用方法,我们使用的私匙和公匙,格式都是为pem格式的字符串或者是文件资源,而如果是PKCS格式的字符串,需要先进行格式化处理,处理方法如下:
另外在解密过程中,需要注意的是数据过长时,一定要进行分段解密,以128个字符长度为例,最长字节数是1024,超过需要分段解密,才能得到正常的解密数据,过程如下:
最近做支付接口时,主要用到的RSA加密方面的问题就是上面这些,以后遇见其他问题再来补充完善!
<?php /** * rsa * 需要 openssl 支持 * * */ class Rsa { private static $_instance; //类初始化操作 function __construct () { } //类销毁操作 function __destruct () { } //公用的静态方法,定义静态变量为当前类的实例 public static function instance() { if (self::$_instance == null) { self::$_instance = new self; } return self::$_instance; } /** * 生成一对RSA的公匙和私匙 * @param unknown_type $bits 钥匙对的字节数 * 返回一对RSA钥匙 */ public function create($bits = 1024) { $rsa = openssl_pkey_new(array('private_key_bits' => $bits,'private_key_type' => OPENSSL_KEYTYPE_RSA)); //得到私匙 openssl_pkey_export($rsa, $privatekey); $publickey = openssl_pkey_get_details($rsa); //得到公匙 $publickey = $publickey['key']; return array( 'privatekey' => $privatekey, 'publickey' => $publickey ); } /** * 公匙加密 使用公匙对信息进行加密处理 * @param unknown_type $sourcestr 待加密数据 * @param unknown_type $publickey RSA公匙(pem格式) * 加密成功返回加密字符串,失败返回FALSE */ function publickey_encodeing($sourcestr, $publickey) { //先将rsa公匙转化为openssl公匙 $pubkeyid = openssl_get_publickey($publickey); //使用openssl加密方法加密 /** * openssl公匙加密 * $sourcestr 待加密数据 * $crypttext 加密后数据 * $pubkeyid openssl公匙 * 成功返回加密后的数据,失败返回false */ if (openssl_public_encrypt($sourcestr, $crypttext, $pubkeyid, OPENSSL_PKCS1_PADDING)) { return $crypttext; } return FALSE; } c7a2 /** * 公匙解密 * @param unknown_type $crypttext 待解密数据 * @param unknown_type $publickey rsa公匙(pem格式或资源) * */ function publickey_decodeing($crypttext, $publickey) { $pubkeyid = openssl_get_publickey($publickey); if (openssl_public_decrypt($crypttext, $sourcestr, $pubkeyid, OPENSSL_PKCS1_PADDING)) { return $sourcestr; } return FALSE; } /** * 私匙解密 同公匙解密 * @param unknown_type $crypttext * @param unknown_type $privatekey * */ function privatekey_decodeing($crypttext, $privatekey) { $prikeyid = openssl_get_privatekey($privatekey); if (openssl_private_decrypt($crypttext, $sourcestr, $prikeyid, OPENSSL_PKCS1_PADDING)) { return $sourcestr; } return FALSE; } /** * 私匙加密 同公匙加密 * @param unknown_type $sourcestr * @param unknown_type $privatekey * */ function privatekey_encodeing($sourcestr, $privatekey) { $prikeyid = openssl_get_privatekey($privatekey); if (openssl_private_encrypt($sourcestr, $crypttext, $prikeyid, OPENSSL_PKCS1_PADDING)) { return $crypttext; } return FALSE; } /** * RSA私匙签名 * @param unknown_type $sourcestr 待签名数据 * @param unknown_type $privatekey rsa私匙(pem格式或资源) * 返回签名后的字符串 */ function sign($sourcestr, $privatekey) { //先将RSA私匙转化为openssl私匙 $pkeyid = openssl_get_privatekey($privatekey); //签名,$signature为签名后的字符串 openssl_sign($sourcestr, $signature, $pkeyid); //释放资源 openssl_free_key($pkeyid); return $signature; } /** * RSA公匙验签 * @param unknown_type $sourcestr 待签名数据 * $signature 私匙签名后的字符串(未经过base64编码的) * @param unknown_type $publickey rsa公匙(pem格式或资源) * 返回验证签名结果 * */ function verify($sourcestr, $signature, $publickey) { //先将rsa公匙转化为openssl公匙 $pkeyid = openssl_get_publickey($publickey); //验证签名,返回1验签正确,返回0验签错误,-1是函数执行错误 $verify = openssl_verify($sourcestr, $signature, $pkeyid); openssl_free_key($pkeyid); return $verify; } } ?>
以上是RSA加密算法的常用方法,我们使用的私匙和公匙,格式都是为pem格式的字符串或者是文件资源,而如果是PKCS格式的字符串,需要先进行格式化处理,处理方法如下:
/**格式化私钥 将私匙每64个长度取做一串,放在pem格式密匙的每一行中 * $priKey PKCS#1格式的私钥串 * return pem格式私钥, 可以保存为.pem文件 */ function formatPriKey($priKey) { $fKey = "-----BEGIN RSA PRIVATE KEY-----\n"; $len = strlen($priKey); for($i = 0; $i < $len; ) { $fKey = $fKey . substr($priKey, $i, 64) . "\n"; $i += 64; } $fKey .= "-----END RSA PRIVATE KEY-----"; return $fKey; } /**格式化公钥 将公匙每64个长度取做一串,放在pem格式密匙的每一行中 * $pubKey PKCS#1格式的私钥串 * return pem格式公钥, 可以保存为.pem文件 */ function formatPubKey($pubKey) { $fKey = "-----BEGIN PUBLIC KEY-----\n"; $len = strlen($pubKey); for($i = 0; $i < $len; ) { $fKey = $fKey . substr($pubKey, $i, 64) . "\n"; $i += 64; } $fKey .= "-----END PUBLIC KEY-----"; return $fKey; }
另外在解密过程中,需要注意的是数据过长时,一定要进行分段解密,以128个字符长度为例,最长字节数是1024,超过需要分段解密,才能得到正常的解密数据,过程如下:
class MyRsa extends Rsa{ /** * 分段解密 * $data 待解密数据 * $key rsa公匙(pem格式或资源) * $rsa_bit 限定解密最长字节数 * 返回验证签名结果 */ function rsa_decrypt($data, $key, $rsa_bit = 1024) { $inputLen = strlen($data); $offSet = 0; $i = 0; $maxDecryptBlock = $rsa_bit / 8; //128 $de = ''; $cache = ''; // 对数据分段解密 while ($inputLen - $offSet > 0) { if ($inputLen - $offSet > $maxDecryptBlock) { $cache = parent::publickey_decodeing(substr($data, $offSet, $maxDecryptBlock), $key); } else { $cache = parent::publickey_decodeing(substr($data, $offSet, $inputLen - $offSet), $key); } $de = $de . $cache; $i = $i + 1; $offSet = $i * $maxDecryptBlock; } return $de; } }
最近做支付接口时,主要用到的RSA加密方面的问题就是上面这些,以后遇见其他问题再来补充完善!
相关文章推荐
- PHP socket类
- php获取字符串拼音和拼音首字母
- 学PHP避免即将到来的就业危机
- PHP学习的一种习惯
- PHPCMS 实现上一篇、下一篇
- Yii框架操作数据库的几种方式与mysql_escape_string
- 在windows下ftp服务器上传文件错误
- 如果ftp服务器使用windows下IIS创建,通过资源管理器登陆ftp服务器,输入正确的用户名和密码,点击登陆按钮没有反应
- php验证是否为非零整数(正整数、负整数)
- 在PHPstorm编辑器中配置git环境
- php 连接主从数据库
- Laravel 5.1 + OAuth2 PasswordGrant(密码授权模式)
- 20个基于PHP的开源内容管理系统推荐
- php session是否存在被破译的可能?
- PHP Socket请求类
- ubuntu安装phpmyadmin注意事项
- php unserialize报错解决记录
- PhpStorm, XDebug, and DBGp Proxy
- vsFTP 加密传输-自生存证书
- FragmentPagerAdapter+ViewPager 笔记