互联网的发展史上,安全性一直是开发者们至关重视的一个主题,为了实现数据传输安全,咱们须要保证:数据来源(非伪造请求)、数据完整性(没有被人修改过)、数据私密性(密文,没法直接读取)等。虽然如今已经有SSL/TLS协议实现的HTTPS协议,可是因在客户端上依赖浏览器的正确实现,并且效率又很低,因此通常的敏感数据(如交易支付信息等)仍是须要咱们使用加密方法来手动加密。算法
虽然对于通常的WEB开发人员来讲,大可没必要深刻了解一些安全相关的底层技术,但学习加密基础知识,使用现有加密相关工具却十分必要。因为工做须要,本身看了些加密相关文章,结合本身的使用经历,完成此文。浏览器
学习如何使用加密以前,咱们须要了解一些加密相关的基础知识。安全
加密算法通常分为两种:对称加密算法和非对称加密算法。函数
对称加密算法是消息发送者和接收者使用同一个密匙,发送者使用密匙加密了文件,接收者使用一样的密匙解密,获取信息。常见的对称加密算法有:des/aes/3des.工具
对称加密算法的特色有:速度快,加密先后文件大小变化不大,可是密匙的保管是个大问题,由于消息发送方和接收方任意一方的密匙丢失,都会致使信息传输变得不安全。学习
与对称加密相对的是非对称加密,非对称加密的核心思想是使用一对相对的密匙,分为公匙和私匙,私匙本身安全保存,而将公匙公开。公钥与私钥是一对,若是用公钥对数据进行加密,只有用对应的私钥才能解密;若是用私钥对数据进行加密,那么只有用对应的公钥才能解密。发送数据前只须要使用接收方的公匙加密就好了。常见的非对称加密算法有RSA/DSA:加密
非对称加密虽然没有密匙保存问题,但其计算量大,加密速度很慢,有时候咱们还须要对大块数据进行分块加密。3d
为了保证数据的完整性,还须要经过散列函数计算获得一个散列值,这个散列值被称为数字签名。其特色有:code
常见的数字签名算法有md5,hash1等算法。接口
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扩展方法,就能够直接请求接口啦。
密码学是一个十分高深的学科,它理论艰深,概念繁多,做为一个WEB开发人员,虽然不须要咱们去研究其底层实现,可是学会使用封装好的方法颇有利于咱们开发。甚至了解其基本实现,也能够举一反三,对算法等有新的理解。