RSA (详见维基百科)算法是现今使用最普遍的公钥密码算法,也是号称地球上最安全的加密算法,与 md5
和 sha1
不一样,到目前为止,也只有极短的RSA加密被破解。
那么什么是公匙密码算法呢,根据密钥的使用方法,能够将密码分为对称密码和公钥密码,接下来咱们来简单说明下它们两个。
对称密码:加密和解密使用同一种密钥的方式,经常使用的算法有 DES
以及 AES
。
公钥密码:加密和解密使用不一样的密码的方式,所以公钥密码一般也称为非对称密码,经常使用的算法有 RSA
。php
因为本文讨论的是 php
的 RSA
加密实例,这里就不详细说明了,对于 RSA
算法有兴趣的朋友能够查看下面的文章
《带你完全理解RSA算法原理》
对于 php
更多加密方式有兴趣的朋友能够查看下面的文章
《PHP数据加密技术与密钥安全管理》linux
为移动端(IOS,安卓)编写 API
接口算法
进行支付、真实信息验证等安全性需求较高的通讯ubuntu
与其余第三方或合做伙伴进行重要的数据传输segmentfault
既然 RSA
是非对称加密,那么就先必须生成所须要的私钥和公钥,以 ubuntu
为例。首先下载开源 RSA
密钥生成工具 openssl
(一般为 linux
系统自带),若是没有,能够经过如下命令进行安装安全
apt-get install openssl
当 openssl
安装完毕后,咱们就能够开始生成私钥、公钥了。首先,生成原始 RSA
私钥文件服务器
openssl genrsa -out rsa_private_key.pem 1024
注:这里生成了一个长度为 1024bit 的密钥,转化为字节就是 128bytephp7
其次,将原始 RSA
私钥转换为 pkcs8
格式less
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
最后,生成 RSA
公钥函数
openssl rsa -in rsa_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;
最后咱们看到输出:
最后要说明的是,公钥、私钥均可以加密,也均可以解密。其中:用公钥加密须要私钥解密,称为“加密”。因为私钥是不公开的,确保了内容的保密,没有私钥没法得到内容;用私钥加密须要公钥解密,称为“签名”。因为公钥是公开的,任何人均可以解密内容,但只能用发布者的公钥解密,验证了内容是该发布者发出的。