您的位置:首页 > 其它

RSA非对称加解密

2017-05-09 10:05 169 查看
RSA加密算法的数字证书操作

最早以前的加密算法是对称加密

(1)甲方选择某一种加密规则,对信息进行加密;

(2)乙方使用同一种规则,对信息进行解密。

最大弱点:甲方必须把加密规则告诉乙方,否则无法解密。保存和传递密钥,就成了最头疼的问题。

非对称加密算法

(1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。

  (2)甲方获取乙方的公钥,然后用它对信息加密。

  (3)乙方得到加密后的信息,用私钥解密。

数字签名

为了保证数据的完整性,还需要通过散列函数计算得到一个散列值,这个散列值被称为数字签名。其特点有:

· 无论原始数据是多大,结果的长度相同的;

· 输入一样,输出也相同;

· 对输入的微小改变,会使结果产生很大的变化;

· 加密过程不可逆,无法通过散列值得到原来的数据;

常见的数字签名算法有md5,hash1等算法。

PHP的openssl扩展

openssl扩展使用openssl加密扩展包,封装了多个用于加密解密相关的PHP函数,极大地方便了对数据的加密解密。 常用的函数有:

对称加密相关:

string openssl_encrypt ( string $data , string $method , string $password)

其中$data为其要加密的数据,$method是加密要使用的方法,$password是要使用的密匙,函数返回加密后的数据;

其中$method列表可以使用openssl_get_cipher_methods()来获取,我们选取其中一个使用,$method列表形如:

Array(
0 => aes-128-cbc,   // aes加密
1 => des-ecb,       // des加密
2 => des-ede3,      // 3des加密
...
)

其解密函数为 string openssl_encrypt ( string $data , string
$method , string $password)

非对称加密相关:

openssl_get_publickey();openssl_pkey_get_public();      // 从证书导出公匙;
openssl_get_privatekey();openssl_pkey_get_private();    // 从证书导出私匙;

它们都只需要传入证书文件(一般是.pem文件);
openssl_public_encrypt(string $data , string &$crypted , mixed $key [, int $padding = OPENSSL\_PKCS1\_PADDING ] )

使用公匙加密数据,其中$data是要加密的数据;$crypted是一个引用变量,加密后的数据会被放入这个变量中;$key是要传入的公匙数据;由于被加密数据分组时,有可能不会正好为加密位数bit的整数倍,所以需要$padding(填充补齐),$padding的可选项有
OPENSSL_PKCS1_PADDING, OPENSSL_NO_PADDING,分别为PKCS1填充,或不使用填充;
与此方法相对的还有(传入参数一致):
openssl_private_encrypt();  // 使用私匙加密;
openssl_private_decrypt();  // 使用私匙解密;
openssl_private_decrypt();  // 使用公匙解密;

还有签名和验签函数:
bool openssl_sign ( string $data , string &$signature , mixed $priv_key_id [, mixed $signature_alg = OPENSSL_ALGO_SHA1 ] )
int openssl_verify ( string $data , string $signature , mixed $pub_key_id [, mixed $signature_alg = OPENSSL_ALGO_SHA1 ] )

签名函数:$data为要签名的数据;$signature为签名结果的引用变量;$priv_key_id为签名所使用的私匙;$signature_alg为签名要使用的算法,其算法列表可以使用openssl_get_md_methods
()得到,形如:
array(
0 => MD5,
1 => SHA1,
2 => SHA256,
...
)


验签函数:与签名函数相对,只不过它要传入与私匙对应的公匙;其结果为签名验证结果,1为成功,0为失败,-1则表示错误;

加密实例

以下是一个非对称加密使用的小例子:

// 获取公匙
$pub_key = openssl_get_publickey('test.pem');
$encrypted = '';
// 对数据分块加密
for ($offset = 0, $length = strlen($raw_msg); $offset < $length; $offset += $key_size){
$encryptedBlock = '';
$data = substr($raw_msg, $offset, $key_size)
if (!openssl_public_encrypt($data, $encryptedBlock, $pub_key, OPENSSL_PKCS1_PADDING)){
return '';
} else {
$encrypted .= $encryptedBlock;
}
return $encrypted;

而对称加密就非常简单了,直接使用ssl_encrypt()函数即可;

当然一些接口可能会对加密方法进行不同的要求,如不同的padding,加密块大小等等,这些就需要使用者自己调整了。

因为我们是在HTTP协议之上处理的数据,所以数据加密完成后,就可以直接发送了,不用再考虑底层的传输,使用cURL或SOAP扩展方法,就可以直接请求接口啦。

 

PHP中使用RSA

作为一个PHPer,当然还要提一下在 PHP 中如何使用 RSA 加密,所用工具依然是强大的openssl扩展:

# 从pfx文件中提取私钥和证书(需要传入密码 $password):
   openssl_pkcs12_read($file_content, $key, $password);
   $key['pkey'] => 私钥
   $key['cert'] => 证书
# 解析x.509证书
   openssl_x509_read($cert);
# 以pkcs7加密标准加解密/签名验签数据:需要注意pkcs7操作都需要使用一个临时文件,多进程时要考虑一下文件冲突问题,还有别忘了最后释放临时文件。
   openssl_pkcs7_encrypt()/openssl_pkcs7_decrypt()
   openssl_pkcs7_sign()/openssl_pkcs7_verify()    
# 从字符串中获取公私钥:
   openssl_pkey_get_private()/openssl_pkey_get_public()
# RSA以pkcs#12标准加解密/签名验签数据:
   openssl_private(public)_encrypt()/openssl_private(public)_decrypt()


这是自己的整理
基于 redis 字符串 string 类型的简单缓存实战

基于 redis 列表 list 类型的简单队列实战

基于 redis 字符串 setnx 的悲观锁实战

基于 redis 事务的乐观锁实战

基于 redis 的发布订阅实战
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  rsa 解密 加密 算法 数据