记录下公司内部接口对接加密验签技术方案
解密逻辑,先通过公钥验证签名(传入密文msg和sign),在通过私钥把code解密出来得到aes的秘钥以及iv,然后把msg根据得到的aes的key和iv解密出来得到消息体文明(得到明文后去掉填充)。
$rt['sta'] = "1"; $rt['msg'] = "算你狠"; $returnjson = json_encode($rt); $rt1=zs_clear2cipher($returnjson, $logname = ''); print_r($rt1); $rt2=zs_cipher2clear($rt1['rs']['sign'], $rt1['rs']['code'], $rt1['rs']['msg']); print_r($rt2); die;
//真诚软件内部接口对接代替mcrypt_decrypt的方案wl@20230803 function zs_clear2cipher($json_str, $logname = '') { //从配置文件读取rsa公钥和私钥,并且把一行的转化成多行的php能使用的格式 $private_key = format_rsa_pri(config("zhensoft_api")['private_key']); $public_key = format_rsa_pub(config("zhensoft_api")['public_key']); //先转化成数组,然后把null转化成空字符串在转化为json字符串 $arr = json_decode($json_str, 1); $cleanarr = null_filter($arr); //把null转化成空字符串 $json_str = json_encode($cleanarr, JSON_UNESCAPED_UNICODE); //$content为原文,使用函数生成16位的随机串,作为aes的加密的key和iv $msg_cleartext = $json_str; $randstr = random(16); $iv = $randstr; $key = $randstr; //php低版本aes加密方式(已废弃) //$aes_msg_ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $msg_cleartext, MCRYPT_MODE_CBC, $iv); //$base64_aes_msg_ciphertext = base64_encode($aes_msg_ciphertext); //这段代码的作用是将字符串 $cleartext 进行填充,使其长度变为 16 的倍数。如果 $cleartext 的长度不是 16 的倍数,那么会使用空字符 \0 进行填充,直到长度满足要求。这是为了确保使用 AES 加密算法时,输入的数据长度符合要求,因为 AES 加密算法要求输入的数据长度必须是 16 的倍数。 $str_padded = $msg_cleartext; if (strlen($str_padded) % 16) { $str_padded = str_pad($str_padded, strlen($str_padded) + 16 - strlen($str_padded) % 16, "\0"); } $msg_cleartext = $str_padded; //使用aes对$cleartext进行aes加密然后base64得到$base64_aes_ciphertext //先进行上面的填充,然后再aes,无填充加密,php高版本aes加密方式openssl_encrypt代替mcrypt_encrypt $aes_msg_ciphertext = openssl_encrypt($msg_cleartext, 'AES-128-CBC', $key, OPENSSL_NO_PADDING, $iv); $base64_aes_msg_ciphertext = base64_encode($aes_msg_ciphertext); //测试代码 //$aes_msg_ciphertext = openssl_encrypt($msg_cleartext, 'AES-128-CBC', $key, 1, $iv); //$base64_aes_msg_ciphertext = base64_encode($aes_msg_ciphertext); //使用公钥对key和iv加密然后再base64生成code,因为被加密串是16位,所以加密后的长度也是固定的。 $pu_key = openssl_pkey_get_public($public_key); //这个函数可用来判断公钥是否是可用的 openssl_public_encrypt($randstr, $pub_code_ciphertext, $pu_key); //公钥加密 $base64_pub_code_ciphertext = base64_encode($pub_code_ciphertext); //使用私钥对加密后台的消息体进行签名,接口接受数据方需要先验证签名,判断加密消息体是否被篡改。 $sign = sign($base64_aes_msg_ciphertext, $private_key); $data['msg'] = $base64_aes_msg_ciphertext; $data['sign'] = $sign; $data['code'] = $base64_pub_code_ciphertext; //记录日志 logRes("明文:" . $json_str . "\r\n返回签名sign:" . $data['sign'] . "\r\n返回code:" . $data['code'] . "\r\n返回msg:" . $data['msg'], $logname); //返回参数 $rt['sta'] = "1"; $rt['msg'] = "ok"; $rt['rs'] = $data; return $rt; } //真诚软件内部接口对接代替mcrypt_decrypt的方案wl@20230803 function zs_cipher2clear($resign, $recode, $remsg, $logname = '') { //从配置文件读取rsa公钥和私钥,并且把一行的转化成多行的php能使用的格式 $private_key = format_rsa_pri(config("zhensoft_api")['private_key']); $public_key = format_rsa_pub(config("zhensoft_api")['public_key']); $pri_key = openssl_pkey_get_private($private_key); //这个函数可用来判断私钥是否是可用的,可用返回资源id Resource id $pu_key = openssl_pkey_get_public($public_key); //这个函数可用来判断公钥是否是可用的 //验证签名使用公钥 $check_sign_flag = verity($remsg, $resign, $public_key); if (!$check_sign_flag) { $rt['sta'] = "0"; $rt['msg'] = "签名验证失败!"; return $rt; } //解密code拿到aes的iv和key openssl_private_decrypt(base64_decode($recode), $randstr, $pri_key); //私钥解密 $key = $randstr; $iv = $randstr; //有了aes的key和iv在解密$remsg //$msg_cleartext = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($remsg), MCRYPT_MODE_CBC, $iv); $msg_cleartext = openssl_decrypt(base64_decode($remsg), 'aes-128-cbc', $key, OPENSSL_NO_PADDING, $iv); //过滤字符串中特殊字符 $msg_cleartext = rtrim(rtrim($msg_cleartext, chr(0)), chr(7)); //去掉最后大括号右侧的字符,填充物去掉,新增强逻辑20230802 $msg_cleartext = removeRightCharactersAfterLastBracket($msg_cleartext); $msg_cleartext = str_replace(array("\r\n", "\r", "\n", "\0"), "", $msg_cleartext); //记录日志 logRes("传入密文签名sign:" . $resign . "\r\n传入密文code:" . $recode . "\r\n传入密文msg:" . $remsg . "\r\n解析后的明文:" . $msg_cleartext, $logname = ''); $rt['sta'] = "1"; $rt['msg'] = "ok"; $rt['rs'] = $msg_cleartext; return $rt; }
版权声明:若无特殊注明,本文皆为《菜鸟站长》原创,转载请保留文章出处。
本文链接:记录下公司内部接口对接加密验签技术方案 - https://www.wlphp.com/?post=409