互联网中,数据交互 数据安全是非常重要的,为了数据的安全,存储在cookie及redis、session中的值是什么样的?
正常情况下,就是数据本身,没有经过加密的,
但是根据项目的安全,数据的安全日益重要起来。
这就需要对数据进行加解密处理了,
部分说明:
RSA公钥与钥匙生成方式
生成的每一行代码都是64位长度的字符串
openssl函数使用方法
先了解下 加密、解密常用的方式有哪几种:
加密基础
学习如何使用加密之前,我们需要了解一些加密相关的基础知识。
加密算法一般分为两种:对称加密算法和非对称加密算法。
对称加密
对称加密算法是消息发送者和接收者使用同一个密匙,发送者使用密匙加密了文件,接收者使用同样的密匙解密,获取信息。常见的对称加密算法有:des/aes/3des.
对称加密算法的特点有:速度快,加密前后文件大小变化不大,但是密匙的保管是个大问题,因为消息发送方和接收方任意一方的密匙丢失,都会导致信息传输变得不安全。
非对称加密
与对称加密相对的是非对称加密,非对称加密的核心思想是使用一对相对的密匙,分为公匙和私匙,私匙自己安全保存,而将公匙公开。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。发送数据前只需要使用接收方的公匙加密就行了。常见的非对称加密算法有RSA/DSA:
非对称加密虽然没有密匙保存问题,但其计算量大,加密速度很慢,有时候我们还需要对大块数据进行分块加密。
数字签名
为了保证数据的完整性,还需要通过散列函数计算得到一个散列值,这个散列值被称为数字签名。其特点有:
无论原始数据是多大,结果的长度相同的;
输入一样,输出也相同;
对输入的微小改变,会使结果产生很大的变化;
加密过程不可逆,无法通过散列值得到原来的数据;
常见的数字签名算法有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)
非对称加密相关:
RSA加减密
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填充,或不使用填充;
加密实例
以下是一个加减密使用的小例子:
//var_dump(openssl_get_cipher_methods()); var_dump(openssl_cipher_iv_length('des-ede3')); //得到这个加密方法需要的 位数 $iv = openssl_random_pseudo_bytes(16); //需要知道加密iv 的向量的位数 $des3 = base64_encode(openssl_encrypt('songyongzhan', 'des-ede3', 'abcd444444444444', OPENSSL_RAW_DATA)); //$des3_cbc = base64_encode(openssl_encrypt('songyongzhan', 'des-ede3-cbc', 'abcd444444444444', 0, $iv)); var_dump($des3); //var_dump($des3_cbc); // // echo sprintf("DES-CBC length:%s\n", openssl_cipher_iv_length('DES-CBC')); echo sprintf("des-ecb length:%s\n", openssl_cipher_iv_length('des-ecb')); $desecb = base64_encode(openssl_encrypt('songyongzhan', 'des-ecb', 'abcd444444444444', OPENSSL_RAW_DATA)); $desecb2 = base64_encode(openssl_encrypt('songyongzhan', 'des-ecb', 'abcd444444444444')); echo sprintf("desecb:%s ---length: %d ^^^^ desecb2:%s ---length: %d \n", $desecb, strlen($desecb), $desecb2, strlen($desecb2)); echo sprintf("desecb:%s ^^^^ desecb2解密:%s \n", openssl_decrypt(base64_decode($desecb), 'des-ecb', 'abcd444444444444', OPENSSL_RAW_DATA), openssl_decrypt(base64_decode($desecb2), 'des-ecb', 'abcd444444444444')); /** * openssl_encrypt 加密出来字符串随 要加密的数据长度 而变化, 加密数据越大 生成的加密字符串越长。 * * 第四个参数 options 如果不 为0 一般情况下 传OPENSSL_RAW_DATA * * $iv 向量 长度根据 openssl_cipher_iv_length('des-ecb'); 根据这这个方法返回的长度 使用 openssl_random_pseudo_bytes($length); * 去自动生成$iv。 如果长度为 0 则不需要传递。 * $fun='des-ecb'; * * if($num=openssl_cipher_iv_length($fun)) * $iv=openssl_random_pseudo_bytes($num); * else * $iv=''; * * 这样就会拿到一个最合适的iv * * * */ //var_dump($v); $data = openssl_encrypt('b', 'aes-128-cbc', 'abcd', 0, $iv); //$data = openssl_encrypt('songyongzhan', 'aes-128-cbc', 'abcd', OPENSSL_RAW_DATA); $data = base64_encode($data); var_dump($data); $re = openssl_decrypt(base64_decode($data), 'aes-128-cbc', 'abcd', 0, $iv); //$re = openssl_decrypt(base64_decode($data), 'aes-128-cbc', 'abcd', OPENSSL_RAW_DATA); var_dump($re); var_dump(openssl_get_publickey()); /** * array(182) { [0]=> string(11) "AES-128-CBC" [1]=> string(11) "AES-128-CFB" [2]=> string(12) "AES-128-CFB1" [3]=> string(12) "AES-128-CFB8" [4]=> string(11) "AES-128-CTR" [5]=> string(11) "AES-128-ECB" [6]=> string(11) "AES-128-OFB" [7]=> string(11) "AES-128-XTS" [8]=> string(11) "AES-192-CBC" [9]=> string(11) "AES-192-CFB" [10]=> string(12) "AES-192-CFB1" [11]=> string(12) "AES-192-CFB8" [12]=> string(11) "AES-192-CTR" [13]=> string(11) "AES-192-ECB" [14]=> string(11) "AES-192-OFB" [15]=> string(11) "AES-256-CBC" [16]=> string(11) "AES-256-CFB" [17]=> string(12) "AES-256-CFB1" [18]=> string(12) "AES-256-CFB8" [19]=> string(11) "AES-256-CTR" [20]=> string(11) "AES-256-ECB" [21]=> string(11) "AES-256-OFB" [22]=> string(11) "AES-256-XTS" [23]=> string(6) "BF-CBC" [24]=> string(6) "BF-CFB" [25]=> string(6) "BF-ECB" [26]=> string(6) "BF-OFB" [27]=> string(16) "CAMELLIA-128-CBC" [28]=> string(16) "CAMELLIA-128-CFB" [29]=> string(17) "CAMELLIA-128-CFB1" [30]=> string(17) "CAMELLIA-128-CFB8" [31]=> string(16) "CAMELLIA-128-ECB" [32]=> string(16) "CAMELLIA-128-OFB" [33]=> string(16) "CAMELLIA-192-CBC" [34]=> string(16) "CAMELLIA-192-CFB" [35]=> string(17) "CAMELLIA-192-CFB1" [36]=> string(17) "CAMELLIA-192-CFB8" [37]=> string(16) "CAMELLIA-192-ECB" [38]=> string(16) "CAMELLIA-192-OFB" [39]=> string(16) "CAMELLIA-256-CBC" [40]=> string(16) "CAMELLIA-256-CFB" [41]=> string(17) "CAMELLIA-256-CFB1" [42]=> string(17) "CAMELLIA-256-CFB8" [43]=> string(16) "CAMELLIA-256-ECB" [44]=> string(16) "CAMELLIA-256-OFB" [45]=> string(9) "CAST5-CBC" [46]=> string(9) "CAST5-CFB" [47]=> string(9) "CAST5-ECB" [48]=> string(9) "CAST5-OFB" [49]=> string(7) "DES-CBC" [50]=> string(7) "DES-CFB" [51]=> string(8) "DES-CFB1" [52]=> string(8) "DES-CFB8" [53]=> string(7) "DES-ECB" [54]=> string(7) "DES-EDE" [55]=> string(11) "DES-EDE-CBC" [56]=> string(11) "DES-EDE-CFB" [57]=> string(11) "DES-EDE-OFB" [58]=> string(8) "DES-EDE3" [59]=> string(12) "DES-EDE3-CBC" [60]=> string(12) "DES-EDE3-CFB" [61]=> string(13) "DES-EDE3-CFB1" [62]=> string(13) "DES-EDE3-CFB8" [63]=> string(12) "DES-EDE3-OFB" [64]=> string(7) "DES-OFB" [65]=> string(8) "DESX-CBC" [66]=> string(8) "IDEA-CBC" [67]=> string(8) "IDEA-CFB" [68]=> string(8) "IDEA-ECB" [69]=> string(8) "IDEA-OFB" [70]=> string(10) "RC2-40-CBC" [71]=> string(10) "RC2-64-CBC" [72]=> string(7) "RC2-CBC" [73]=> string(7) "RC2-CFB" [74]=> string(7) "RC2-ECB" [75]=> string(7) "RC2-OFB" [76]=> string(3) "RC4" [77]=> string(6) "RC4-40" [78]=> string(12) "RC4-HMAC-MD5" [79]=> string(8) "SEED-CBC" [80]=> string(8) "SEED-CFB" [81]=> string(8) "SEED-ECB" [82]=> string(8) "SEED-OFB" [83]=> string(11) "aes-128-cbc" [84]=> string(11) "aes-128-ccm" [85]=> string(11) "aes-128-cfb" [86]=> string(12) "aes-128-cfb1" [87]=> string(12) "aes-128-cfb8" [88]=> string(11) "aes-128-ctr" [89]=> string(11) "aes-128-ecb" [90]=> string(11) "aes-128-gcm" [91]=> string(11) "aes-128-ofb" [92]=> string(11) "aes-128-xts" [93]=> string(11) "aes-192-cbc" [94]=> string(11) "aes-192-ccm" [95]=> string(11) "aes-192-cfb" [96]=> string(12) "aes-192-cfb1" [97]=> string(12) "aes-192-cfb8" [98]=> string(11) "aes-192-ctr" [99]=> string(11) "aes-192-ecb" [100]=> string(11) "aes-192-gcm" [101]=> string(11) "aes-192-ofb" [102]=> string(11) "aes-256-cbc" [103]=> string(11) "aes-256-ccm" [104]=> string(11) "aes-256-cfb" [105]=> string(12) "aes-256-cfb1" [106]=> string(12) "aes-256-cfb8" [107]=> string(11) "aes-256-ctr" [108]=> string(11) "aes-256-ecb" [109]=> string(11) "aes-256-gcm" [110]=> string(11) "aes-256-ofb" [111]=> string(11) "aes-256-xts" [112]=> string(6) "bf-cbc" [113]=> string(6) "bf-cfb" [114]=> string(6) "bf-ecb" [115]=> string(6) "bf-ofb" [116]=> string(16) "camellia-128-cbc" [117]=> string(16) "camellia-128-cfb" [118]=> string(17) "camellia-128-cfb1" [119]=> string(17) "camellia-128-cfb8" [120]=> string(16) "camellia-128-ecb" [121]=> string(16) "camellia-128-ofb" [122]=> string(16) "camellia-192-cbc" [123]=> string(16) "camellia-192-cfb" [124]=> string(17) "camellia-192-cfb1" [125]=> string(17) "camellia-192-cfb8" [126]=> string(16) "camellia-192-ecb" [127]=> string(16) "camellia-192-ofb" [128]=> string(16) "camellia-256-cbc" [129]=> string(16) "camellia-256-cfb" [130]=> string(17) "camellia-256-cfb1" [131]=> string(17) "camellia-256-cfb8" [132]=> string(16) "camellia-256-ecb" [133]=> string(16) "camellia-256-ofb" [134]=> string(9) "cast5-cbc" [135]=> string(9) "cast5-cfb" [136]=> string(9) "cast5-ecb" [137]=> string(9) "cast5-ofb" [138]=> string(7) "des-cbc" [139]=> string(7) "des-cfb" [140]=> string(8) "des-cfb1" [141]=> string(8) "des-cfb8" [142]=> string(7) "des-ecb" [143]=> string(7) "des-ede" [144]=> string(11) "des-ede-cbc" [145]=> string(11) "des-ede-cfb" [146]=> string(11) "des-ede-ofb" [147]=> string(8) "des-ede3" [148]=> string(12) "des-ede3-cbc" [149]=> string(12) "des-ede3-cfb" [150]=> string(13) "des-ede3-cfb1" [151]=> string(13) "des-ede3-cfb8" [152]=> string(12) "des-ede3-ofb" [153]=> string(7) "des-ofb" [154]=> string(8) "desx-cbc" [155]=> string(13) "id-aes128-CCM" [156]=> string(13) "id-aes128-GCM" [157]=> string(14) "id-aes128-wrap" [158]=> string(13) "id-aes192-CCM" [159]=> string(13) "id-aes192-GCM" [160]=> string(14) "id-aes192-wrap" [161]=> string(13) "id-aes256-CCM" [162]=> string(13) "id-aes256-GCM" [163]=> string(14) "id-aes256-wrap" [164]=> string(24) "id-smime-alg-CMS3DESwrap" [165]=> string(8) "idea-cbc" [166]=> string(8) "idea-cfb" [167]=> string(8) "idea-ecb" [168]=> string(8) "idea-ofb" [169]=> string(10) "rc2-40-cbc" [170]=> string(10) "rc2-64-cbc" [171]=> string(7) "rc2-cbc" [172]=> string(7) "rc2-cfb" [173]=> string(7) "rc2-ecb" [174]=> string(7) "rc2-ofb" [175]=> string(3) "rc4" [176]=> string(6) "rc4-40" [177]=> string(12) "rc4-hmac-md5" [178]=> string(8) "seed-cbc" [179]=> string(8) "seed-cfb" [180]=> string(8) "seed-ecb" [181]=> string(8) "seed-ofb" } string(24) "82XWmUHbd/yF9psJhlHPJg==" string(12) "songyongzhan" [Finished in 0.2s] */
// 获取公匙
$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,加密块大小等等,这些就需要使用者自己调整了。
如果系统是长连接,会话可以通过php直接存入到cookie
如果单单是接口,那么需要客户端自己存入cookie
简单说明:cookie中的值必须是经过加密处理的。
AES加密
DES加密
RSA加密
经过AES中的base64_encode加密后,在传输的过程中,
+ 会变成 空格
因此需要对其进行安全转换:
function base64encode($data, $urlsafe = FALSE) { $data = base64_encode($data); return $urlsafe ? strtr($data, '+/', '-_') : $data; } function base64decode($data, $urlsafe = FALSE) { return base64_decode($urlsafe ? strtr($data, '-_', '+/') : $data); }
因此对base64_encode 进行了封装处理,其实就是进行吧 字符的替换工作,这样在传输的过程中就不会出现错误了。
解密的时候,重新把替换的字符替换回来,这两个函数就是做两件事情用的。
随机生成了 openssl_random_pseudo_bytes(16); 16个伪字节符,用于加密更安全 通过16个字符 function AESEncrypt($data, $key, $urlsafe = FALSE) { //openssl_get_cipher_methods if ($data && $key) { $iv = openssl_random_pseudo_bytes(16); //随机生成一个伪字节 echo random_bytes(5); $data = base64encode($iv . openssl_encrypt($data, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv), $urlsafe); } return $data; } function AESDecrypt($data, $key, $urlsafe = FALSE) { if (strlen($data) >= 16 + 16 && $key) { $data = base64decode($data, $urlsafe); $data = openssl_decrypt(substr($data, 16), 'aes-128-cbc', $key, OPENSSL_RAW_DATA, substr($data, 0, 16)); } return $data; } $key="456"; $pass= AESEncrypt('song',$key); echo $pass; echo "<br>"; $src=AESDecrypt($pass,$key); echo $src; openssl_encrypt() openssl_decrypt() -------------------------- DES 加密 DES3 加密 以下这两种加密方式,其实也是openssl 加密中的,只不过是 加密的方法不一样, 不要以为是其他的加密方式。 $data = openssl_encrypt($data, 'des-ecb', $key); $data = openssl_decrypt($data, 'des-ecb', $key); 就是第二个参数传递不一样。 function DESEncrypt($data, $key, $urlsafe = FALSE) { if ($data && $key) { $data = openssl_encrypt($data, 'des-ecb', $key); $urlsafe && $data = strtr($data, '+/', '-_'); } return $data; } function DESDecrypt($data, $key, $urlsafe = FALSE) { if ($data && $key) { $urlsafe && $data = strtr($data, '-_', '+/'); $data = openssl_decrypt($data, 'des-ecb', $key); } return $data; } DES3也是一样的方式: function DES3Encrypt($data, $key, $urlsafe = FALSE) { if ($data && $key) { $data = openssl_encrypt($data, 'des-ede3', $key); $urlsafe && $data = strtr($data, '+/', '-_'); } return $data; } function DES3Decrypt($data, $key, $urlsafe = FALSE) { if ($data && $key) { $urlsafe && $data = strtr($data, '-_', '+/'); if ($result = openssl_decrypt($data, 'des-ede3', $key, OPENSSL_ZERO_PADDING)) { $padding = ord(substr($result, -1)); //DESede/ECB/ISO10126Padding $padding <= 8 && $result = substr($result, 0, -$padding); } return $result; } else return $data; } /** 此方法用于生成 唯一用于id的的, 适用于大并发情况下,生成唯一id */ function getGUID() { //32 if (function_exists('com_create_guid')) return trim(com_create_guid(), '{}'); else { //mt_srand((double) microtime() * 10000); $charid = strtoupper(md5(uniqid(rand(), TRUE))); $result = substr($charid, 0, 8) . '-' . substr($charid, 8, 4) . '-' . substr($charid, 12, 4) . '-' . substr($charid, 16, 4) . '-' . substr($charid, 20, 12); return $result; } }