收集了PHP的加解密方法
与java交互时需要注意的地方
- 业务报文通过 3DES 进行加解密,加密模式为 ECB
linux平台使用des-ede3,window 平台使用 des-ede3-ecb,des-ede3
base64_encode(openssl_encrypt($plainText, 'des-ede3', 'key', OPENSSL_RAW_DATA));
随机字符
base64_encode(openssl_random_pseudo_bytes($length));
RC4
对称加密算法,解密只需要再调用一遍即可
/*
* rc4加密算法
* $pwd 密钥
* $data 要加密的数据
*/
function rc4_encrypt($pwd, $data)
{
$cipher = '';
$key[] = "";
$box[] = "";
$pwd_length = strlen($pwd);
$data_length = strlen($data);
for ($i = 0; $i < 256; $i++) {
$key[$i] = ord($pwd[$i % $pwd_length]);
$box[$i] = $i;
}
for ($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $key[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for ($a = $j = $i = 0; $i < $data_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$k = $box[(($box[$a] + $box[$j]) % 256)];
$cipher .= chr(ord($data[$i]) ^ $k);
}
return $cipher;
}
AES
/**
* AES加密
*/
function aes_encript($plaintext ,$key='ebg.conzhu.net', $cipher='AES-256-CBC'){
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
return base64_encode( $iv.$hmac.$ciphertext_raw );
}
/**
* AES解密
* @param $ciphertext
* @param string $key
* @param string $cipher
* @return string
*/
function aes_decrypt($ciphertext, $key='ebg.conzhu.net',$cipher='AES-256-CBC'){
$c = base64_decode($ciphertext);
$ivlen = openssl_cipher_iv_length($cipher);
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, $sha2len=32);
$ciphertext_raw = substr($c, $ivlen+$sha2len);
$original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
if (function_exists('hash_equals')){
if (hash_equals($hmac, $calcmac)){
return $original_plaintext;
}else{
return false;
}
}else{
if ($hmac === $calcmac){
return $original_plaintext;
}else{
return false;
}
}
}
3DES
/**
* 3DES加密
* @param string $data 待加密的数据
* @param string $key 加密密钥
* @return string
*/
function encrypt_3des($data, $key)
{
return base64_encode(openssl_encrypt($data, "des-ede3", $key));
}
/**
* 3DES解密
* @param string $data 待解密的数据
* @param string $key 解密密钥
* @return string
*/
function decrypt_3des($data, $key)
{
return openssl_decrypt(base64_decode($data), "des-ede3", $key);
}
RSA
基本概念
- 公钥加密,私钥解密
- 私钥签名,公钥验签
密钥格式
- PKCS8(JAVA适用)
- PKCS1(非JAVA适用)
代码示例
/**
* 获取公钥私钥
* @return array
*/
function getPublicKeyAndPrivateKey(){
$resource = openssl_pkey_new();
openssl_pkey_export($resource, $privateKey);
$detail = openssl_pkey_get_details($resource);
return ['publicKey'=>$detail['key'],'privateKey'=>$privateKey];
}
/**
* 公钥加密,明文加密时的长度为[2048bit/8-11]=245,过长会加密失败
* @param $plaintext
* @param $publicKey
* @return string
*/
function encryptWithPublicKey($plaintext,$publicKey){
$crypto = '';
if ($plaintext){
foreach (str_split($plaintext, 245) as $chunk) {
openssl_public_encrypt($chunk, $encryptData, $publicKey);
$crypto .= $encryptData;
}
$crypto = base64_encode($crypto);
}
return $crypto;
}
/
**
* 私钥解密
* @param $encryptData
* @param $privateKey
* @return mixed
*/
function decryptWithPrivateKey($encryptData, $privateKey){
$crypto = '';
foreach (str_split(base64_decode($encryptData), 256) as $chunk) {
openssl_private_decrypt($chunk, $decryptData, $privateKey);
$crypto .= $decryptData;
}
return $crypto;
}
/**
* 私钥签名
* @param $original_str
* @param $private_key
* @return string
*/
function signWithPrivateKey($original_str, $private_key)
{
$key = openssl_get_privatekey($private_key);
openssl_sign($original_str, $sign, $key, 'SHA256');
openssl_free_key($key);
$sign = base64_encode($sign);//最终的签名
return $sign;
}
/**
* 公钥验签
* @param $original_str
* @param $sign
* @param $public_key
* @return bool
*/
function checkSignWithPublicKey($original_str, $sign, $public_key)
{
$sign = base64_decode($sign);//得到的签名
$public_key = openssl_get_publickey($public_key);
$result = (bool)openssl_verify($original_str, $sign, $public_key, 'SHA256');
openssl_free_key($public_key);
return $result;
}