首页 > 文章详情 > PHP基于openssl实现的非对称加密操作

PHP基于openssl实现的非对称加密操作

原创 YuanDong 2019-10-07 浏览量(135)
文章简介 使用非对称加密主要是借助openssl的公钥和私钥,用公钥加密私钥解密,或者私钥加密公钥解密。

加密基础

学习如何使用加密之前,我们需要了解一些加密相关的基础知识。
加密算法一般分为两种:对称加密算法和非对称加密算法。

对称加密

对称加密算法是消息发送者和接收者使用同一个密匙,发送者使用密匙加密了文件,接收者使用同样的密匙解密,获取信息。常见的对称加密算法有:des/aes/3des.

对称加密算法的特点有:速度快,加密前后文件大小变化不大,但是密匙的保管是个大问题,因为消息发送方和接收方任意一方的密匙丢失,都会导致信息传输变得不安全。

非对称加密

与对称加密相对的是非对称加密,非对称加密的核心思想是使用一对相对的密匙,分为公匙和私匙,私匙自己安全保存,而将公匙公开。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。发送数据前只需要使用接收方的公匙加密就行了。常见的非对称加密算法有RSA/DSA:

非对称加密虽然没有密匙保存问题,但其计算量大,加密速度很慢,有时候我们还需要对大块数据进行分块加密。

数字签名

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

  • 无论原始数据是多大,结果的长度相同的;
  • 输入一样,输出也相同;
  • 对输入的微小改变,会使结果产生很大的变化;
  • 加密过程不可逆,无法通过散列值得到原来的数据;
  • 常见的数字签名算法有md5,hash1等算法。

使用非对称加密主要是借助openssl的公钥和私钥,用公钥加密私钥解密,或者私钥加密公钥解密。

1.安装openssl和php的openssl扩展

2.生成私钥:openssl genrsa 用于生成rsa私钥文件,生成是可以指定私钥长度和密码保护

openssl genrsa -out rsa_private_key.pem 1024

3.生成公钥:rsa命令用于处理RSA密钥、格式转换和打印信息

openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

4.这里我们使用私钥加密,公钥解密

<?php

//密钥文件的路径
$privateKeyFilePath = 'rsa_private_key.pem';

//公钥文件的路径
$publicKeyFilePath = 'rsa_public_key.pem';

/**
* 生成Resource类型的密钥,如果密钥文件内容被破坏,openssl_pkey_get_private函数返回false
*/
$privateKey = openssl_pkey_get_private(file_get_contents($privateKeyFilePath));

/**
* 生成Resource类型的公钥,如果公钥文件内容被破坏,openssl_pkey_get_public函数返回false
*/
$publicKey = openssl_pkey_get_public(file_get_contents($publicKeyFilePath));


($privateKey && $publicKey) or die('密钥或者公钥不可用');

$originalData = '加密的数据';

///////////////////////////////用私钥加密////////////////////////
$encryptData = '';
if (openssl_private_encrypt($originalData, $encryptData, $privateKey)) {
  //加密后 可以base64_encode后方便在网址中传输 或者打印 否则打印为乱码
  echo '加密成功,加密后数据(base64_encode后)为:', base64_encode($encryptData), PHP_EOL;
} else {
  die('加密失败');
}

///////////////////////////////用公钥解密////////////////////////
$decryptData ='';
if (openssl_public_decrypt($encryptData, $decryptData, $publicKey)) {
  echo '解密成功,解密后数据为:', $decryptData, PHP_EOL;
} else {
  die('解密成功');
}

5.做接口签名验证使用

<?php

/**
 * 获取签名
 *
 * @param string $str            需要加密的字符串
 * @param string $rsaPrivateFile 私钥文件地址
 *
 * @return string
 */
function getRsaSign($str, $rsaPrivateFile)
{
    $privateKey = file_get_contents($rsaPrivateFile);
    $resource   = openssl_get_privatekey($privateKey);
    openssl_sign($str, $sign, $resource, OPENSSL_ALGO_SHA256);
    openssl_free_key($resource);
    return base64_encode($sign);
}

/**
 * 验证签名
 *
 * @param string $sign          需要验证的签名字符串
 * @param string $str           参与加密的字符串
 * @param string $rsaPublicFile 公钥文件地址
 *
 * @return bool
 */
function checkRsaSign($sign, $str, $rsaPublicFile)
{
    $public_key = file_get_contents($rsaPublicFile);
    $resource   = openssl_get_publickey($public_key);
    $result     = openssl_verify($str, base64_decode($sign), $resource, OPENSSL_ALGO_SHA256);
    openssl_free_key($resource);
    return (bool)$result;
}

热门评论 (0)

网友评论 0 条评论 / 0 人参与