收集了PHP的加解密方法

与java交互时需要注意的地方

  • 业务报文通过 3DES 进行加解密,加密模式为 ECB

    linux平台使用des-ede3,window 平台使用 des-ede3-ecb,des-ede3

  1. base64_encode(openssl_encrypt($plainText, 'des-ede3', 'key', OPENSSL_RAW_DATA));

随机字符

  1. base64_encode(openssl_random_pseudo_bytes($length));

RC4

对称加密算法,解密只需要再调用一遍即可

  1. /*
  2. * rc4加密算法
  3. * $pwd 密钥
  4. * $data 要加密的数据
  5. */
  6. function rc4_encrypt($pwd, $data)
  7. {
  8. $cipher = '';
  9. $key[] = "";
  10. $box[] = "";
  11. $pwd_length = strlen($pwd);
  12. $data_length = strlen($data);
  13. for ($i = 0; $i < 256; $i++) {
  14. $key[$i] = ord($pwd[$i % $pwd_length]);
  15. $box[$i] = $i;
  16. }
  17. for ($j = $i = 0; $i < 256; $i++) {
  18. $j = ($j + $box[$i] + $key[$i]) % 256;
  19. $tmp = $box[$i];
  20. $box[$i] = $box[$j];
  21. $box[$j] = $tmp;
  22. }
  23. for ($a = $j = $i = 0; $i < $data_length; $i++) {
  24. $a = ($a + 1) % 256;
  25. $j = ($j + $box[$a]) % 256;
  26. $tmp = $box[$a];
  27. $box[$a] = $box[$j];
  28. $box[$j] = $tmp;
  29. $k = $box[(($box[$a] + $box[$j]) % 256)];
  30. $cipher .= chr(ord($data[$i]) ^ $k);
  31. }
  32. return $cipher;
  33. }

AES

  1. /**
  2. * AES加密
  3. */
  4. function aes_encript($plaintext ,$key='ebg.conzhu.net', $cipher='AES-256-CBC'){
  5. $ivlen = openssl_cipher_iv_length($cipher);
  6. $iv = openssl_random_pseudo_bytes($ivlen);
  7. $ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
  8. $hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
  9. return base64_encode( $iv.$hmac.$ciphertext_raw );
  10. }
  11. /**
  12. * AES解密
  13. * @param $ciphertext
  14. * @param string $key
  15. * @param string $cipher
  16. * @return string
  17. */
  18. function aes_decrypt($ciphertext, $key='ebg.conzhu.net',$cipher='AES-256-CBC'){
  19. $c = base64_decode($ciphertext);
  20. $ivlen = openssl_cipher_iv_length($cipher);
  21. $iv = substr($c, 0, $ivlen);
  22. $hmac = substr($c, $ivlen, $sha2len=32);
  23. $ciphertext_raw = substr($c, $ivlen+$sha2len);
  24. $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
  25. $calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
  26. if (function_exists('hash_equals')){
  27. if (hash_equals($hmac, $calcmac)){
  28. return $original_plaintext;
  29. }else{
  30. return false;
  31. }
  32. }else{
  33. if ($hmac === $calcmac){
  34. return $original_plaintext;
  35. }else{
  36. return false;
  37. }
  38. }
  39. }

3DES

  1. /**
  2. * 3DES加密
  3. * @param string $data 待加密的数据
  4. * @param string $key 加密密钥
  5. * @return string
  6. */
  7. function encrypt_3des($data, $key)
  8. {
  9. return base64_encode(openssl_encrypt($data, "des-ede3", $key));
  10. }
  11. /**
  12. * 3DES解密
  13. * @param string $data 待解密的数据
  14. * @param string $key 解密密钥
  15. * @return string
  16. */
  17. function decrypt_3des($data, $key)
  18. {
  19. return openssl_decrypt(base64_decode($data), "des-ede3", $key);
  20. }

RSA

基本概念

  • 公钥加密,私钥解密
  • 私钥签名,公钥验签

密钥格式

  • PKCS8(JAVA适用)
  • PKCS1(非JAVA适用)

代码示例

  1. /**
  2. * 获取公钥私钥
  3. * @return array
  4. */
  5. function getPublicKeyAndPrivateKey(){
  6. $resource = openssl_pkey_new();
  7. openssl_pkey_export($resource, $privateKey);
  8. $detail = openssl_pkey_get_details($resource);
  9. return ['publicKey'=>$detail['key'],'privateKey'=>$privateKey];
  10. }
  11. /**
  12. * 公钥加密,明文加密时的长度为[2048bit/8-11]=245,过长会加密失败
  13. * @param $plaintext
  14. * @param $publicKey
  15. * @return string
  16. */
  17. function encryptWithPublicKey($plaintext,$publicKey){
  18. $crypto = '';
  19. if ($plaintext){
  20. foreach (str_split($plaintext, 245) as $chunk) {
  21. openssl_public_encrypt($chunk, $encryptData, $publicKey);
  22. $crypto .= $encryptData;
  23. }
  24. $crypto = base64_encode($crypto);
  25. }
  26. return $crypto;
  27. }
  28. /
  29. **
  30. * 私钥解密
  31. * @param $encryptData
  32. * @param $privateKey
  33. * @return mixed
  34. */
  35. function decryptWithPrivateKey($encryptData, $privateKey){
  36. $crypto = '';
  37. foreach (str_split(base64_decode($encryptData), 256) as $chunk) {
  38. openssl_private_decrypt($chunk, $decryptData, $privateKey);
  39. $crypto .= $decryptData;
  40. }
  41. return $crypto;
  42. }
  43. /**
  44. * 私钥签名
  45. * @param $original_str
  46. * @param $private_key
  47. * @return string
  48. */
  49. function signWithPrivateKey($original_str, $private_key)
  50. {
  51. $key = openssl_get_privatekey($private_key);
  52. openssl_sign($original_str, $sign, $key, 'SHA256');
  53. openssl_free_key($key);
  54. $sign = base64_encode($sign);//最终的签名
  55. return $sign;
  56. }
  57. /**
  58. * 公钥验签
  59. * @param $original_str
  60. * @param $sign
  61. * @param $public_key
  62. * @return bool
  63. */
  64. function checkSignWithPublicKey($original_str, $sign, $public_key)
  65. {
  66. $sign = base64_decode($sign);//得到的签名
  67. $public_key = openssl_get_publickey($public_key);
  68. $result = (bool)openssl_verify($original_str, $sign, $public_key, 'SHA256');
  69. openssl_free_key($public_key);
  70. return $result;
  71. }