RSA (详见维基百科)算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法,与
和
- md5
不同,到目前为止,也只有极短的RSA加密被破解。那么什么是公匙密码算法呢,根据密钥的使用方法,可以将密码分为对称密码和公钥密码,接下来我们来简单说明下它们两个。对称密码:加密和解密使用同一种密钥的方式,常用的算法有
- sha1
以及
- DES
。公钥密码:加密和解密使用不同的密码的方式,因此公钥密码通常也称为非对称密码,常用的算法有
- AES
。
- RSA
由于本文讨论的是
的
- php
加密实例,这里就不详细说明了,对于
- RSA
算法有兴趣的朋友可以查看下面的文章
- RSA
更多加密方式有兴趣的朋友可以查看下面的文章 《PHP数据加密技术与密钥安全管理》
- php
接口
- API
既然
是非对称加密,那么就先必须生成所需要的私钥和公钥,以
- RSA
为例。首先下载开源
- ubuntu
密钥生成工具
- RSA
(通常为
- openssl
系统自带),如果没有,可以通过以下命令进行安装
- linux
- apt - get install openssl
当
安装完毕后,我们就可以开始生成私钥、公钥了。首先,生成原始
- openssl
私钥文件
- RSA
- openssl genrsa - out rsa_private_key.pem 1024
注:这里生成了一个长度为 1024bit 的密钥,转化为字节就是 128byte
其次,将原始
私钥转换为
- RSA
格式
- pkcs8
- openssl pkcs8 - topk8 - inform PEM - inrsa_private_key.pem - outform PEM - nocrypt - out private_key.pem
最后,生成
公钥
- RSA
- openssl rsa - inrsa_private_key.pem - pubout - out rsa_public_key.pem
在需要使用的时候,我们将私钥
放在服务器端,公钥发放给需要与我们进行加密通信的一方就可以了。
- rsa_private_key.pem
现在我们可以使用
进行
- php
的加密解密了,但在此之前,你首先要看看你有没有安装或开启
- RSA
的
- php
扩展,可以通过文件输出
- openssl
或者通过命令行输出
- phpinfo()
来查看是否安装开启了此扩展,也可以通过
- php -m | less
函数来判断扩展是否开启,如果没有,则通过该命令进行安装(以
- extension_loaded()
为例):
- ubuntu
- apt - get install php7.0 - openssl
当然,如果你是
操作系统,可以下载对应版本的
- Windows
。
- php_openssl.dll
好了,现在我们来编写一个 php-RSA 的服务器类库,这个类库的工作其实很简单,就是封装一些
针对
- php
操作的函数,方便我们加密解密。
- RSA
- class Rsa {
- private $_config = ['public_key' = >'', 'private_key' = >'', ];
- public
- function __construct($private_key_filepath, $public_key_filepath) {
- $this - >_config['private_key'] = $this - >_getContents($private_key_filepath);
- $this - >_config['public_key'] = $this - >_getContents($public_key_filepath);
- }
- /**
- * @uses 获取文件内容
- * @param $file_path string
- * @return bool|string
- */
- private
- function _getContents($file_path) {
- file_exists($file_path) or die('密钥或公钥的文件路径错误');
- return file_get_contents($file_path);
- }
- /**
- * @uses 获取私钥
- * @return bool|resource
- */
- private
- function _getPrivateKey() {
- $priv_key = $this - >_config['private_key'];
- return openssl_pkey_get_private($priv_key);
- }
- /**
- * @uses 获取公钥
- * @return bool|resource
- */
- private
- function _getPublicKey() {
- $public_key = $this - >_config['public_key'];
- return openssl_pkey_get_public($public_key);
- }
- /**
- * @uses 私钥加密
- * @param string $data
- * @return null|string
- */
- public
- function privEncrypt($data = '') {
- if (!is_string($data)) {
- return null;
- }
- return openssl_private_encrypt($data, $encrypted, $this - >_getPrivateKey()) ? base64_encode($encrypted) : null;
- }
- /**
- * @uses 公钥加密
- * @param string $data
- * @return null|string
- */
- public
- function publicEncrypt($data = '') {
- if (!is_string($data)) {
- return null;
- }
- return openssl_public_encrypt($data, $encrypted, $this - >_getPublicKey()) ? base64_encode($encrypted) : null;
- }
- /**
- * @uses 私钥解密
- * @param string $encrypted
- * @return null
- */
- public
- function privDecrypt($encrypted = '') {
- if (!is_string($encrypted)) {
- return null;
- }
- return (openssl_private_decrypt(base64_decode($encrypted), $decrypted, $this - >_getPrivateKey())) ? $decrypted: null;
- }
- /**
- * @uses 公钥解密
- * @param string $encrypted
- * @return null
- */
- public
- function publicDecrypt($encrypted = '') {
- if (!is_string($encrypted)) {
- return null;
- }
- return (openssl_public_decrypt(base64_decode($encrypted), $decrypted, $this - >_getPublicKey())) ? $decrypted: null;
- }
- }
好了,现在我们调用
类,对数据进行加密解密
- Rsa
- $private_key = 'private_key.pem'; // 私钥路径
- $public_key = 'rsa_public_key.pem'; // 公钥路径
- $rsa = new Rsa($private_key, $public_key);
- $origin_data = '这是一条测试数据';
- $ecryption_data = $rsa - >privEncrypt($origin_data);
- $decryption_data = $rsa - >publicDecrypt($ecryption_data);
- echo '私钥加密后的数据为:'.$ecryption_data;
- echo PHP_EOL;
- echo '公钥解密后的数据为: '.$decryption_data;
- echo PHP_EOL;
最后我们看到输出:
最后要说明的是,公钥、私钥都可以加密,也都可以解密。其中:用公钥加密需要私钥解密,称为“加密”。由于私钥是不公开的,确保了内容的保密,没有私钥无法获得内容;用私钥加密需要公钥解密,称为“签名”。由于公钥是公开的,任何人都可以解密内容,但只能用发布者的公钥解密,验证了内容是该发布者发出的。
来源: https://juejin.im/entry/5a13ddea6fb9a045167cd01c