1、HMAC-SHA256 加密(不可逆无法解密)
假设:
appkey 为:testappkey
appsecret 为:testappsecret
当前时间戳为:1562912285
拼装原串为:testappkey1562912285testappsecret
则 HMAC-SHA256 加密后得到的值:559c4fa92e47b7f148a788300c6a345feddbd327b9fc551f100de679bbb247c5
$string = hash_hmac("sha256",'testappkey1562912285testappsecret','testappsecret'); // 559c4fa92e47b7f148a788300c6a345feddbd327b9fc551f100de679bbb247c52、AES(CipherMode.CBC PaddingMode.PKCS7)加密
假设:
appsecret 为:0688f7a191da4fbab177fd1c8ef19901
aesIV 为:ff465fdecc764337
加密前数据示例:{"settlement_code":["JS19BUB14F5D8D4C"],"random_code":["19BUB14F5D8D4C","19BUAD0E89D780"]}
则 加密后的值为(以下三个方法都一样):{"data":"236agZcupcSsMZghtlmzhb7lEWzGZc3FO5GWQyrSB5kP/y1ESvd+CuBgQiWU/fwAICY/s0mideku/rXSKEb8In41F4SkUVLyLzYoYGed4QTjsqohTM0T6wmbkOiT1TH3"}
$string = '{"settlement_code":["JS19BUB14F5D8D4C"],"random_code":["19BUB14F5D8D4C","19BUAD0E89D780"]}';
$aesIV = 'ff465fdecc764337';
$appsecret = '0688f7a191da4fbab177fd1c8ef19901';
$newText = openssl_encrypt($string,'AES-256-CBC',$appsecret,false,$aesIV);
$newText = openssl_encrypt($string,'AES-256-CBC-HMAC-SHA1',$appsecret,false,$aesIV);
$newText = openssl_encrypt($string,'AES-256-CBC-HMAC-SHA256',$appsecret,false,$aesIV);若不知道使openssl_encrypt的第二个参数传什么方法,则可以使用以下方法再for循环逐个尝试
$method = openssl_get_cipher_methods();
3、AES(CipherMode.CBC PaddingMode.PKCS7)解密
$data = openssl_decrypt($newText,'AES-256-CBC',$appsecret,false,$aesIV);
得到的data即为加密前数据:{"settlement_code":["JS19BUB14F5D8D4C"],"random_code":["19BUB14F5D8D4C","19BUAD0E89D780"]}
4、舌诊的aes加密示例
$key = 'y82caGkvfRvjtRNngcpHzA=='; $age_sex['age'] = $age; $age_sex['sex'] = $sex; $encrypt_data = openssl_encrypt(json_encode($age_sex), 'aes-128-ecb', base64_decode($key), OPENSSL_RAW_DATA); $data['encryptData'] = base64_encode($encrypt_data);
5、舌诊的aes解密示例
$key = 'y82caGkvfRvjtRNngcpHzA=='; $encrypted = base64_decode($param['encryptData']); // $param['encryptData']为舌诊接口返回的待解密数据 $data = json_decode(openssl_decrypt($encrypted, 'aes-128-ecb', base64_decode($key), OPENSSL_RAW_DATA),true);
6、rsa签名(使用私钥生成签名)
/**********************************私钥格式化*************************************/
private function formatPriKey($priKey) {
$fKey = "-----BEGIN PRIVATE KEY-----\n";
$len = strlen($priKey);
for($i = 0; $i < $len; ) {
$fKey = $fKey . substr($priKey, $i, 64) . "\n";
$i += 64;
}
$fKey .= "-----END PRIVATE KEY-----";
return $fKey;
}
/**********************************公钥格式化*************************************/
private function formatPubKey($pubKey) {
$fKey = "-----BEGIN PUBLIC KEY-----\n";
$len = strlen($pubKey);
for($i = 0; $i < $len; ) {
$fKey = $fKey . substr($pubKey, $i, 64) . "\n";
$i += 64;
}
$fKey .= "-----END PUBLIC KEY-----";
return $fKey;
}
/**
* 配置私钥
* openssl_pkey_get_private这个函数可用来判断私钥是否是可用的,可用,返回资源
* @return bool|resource
*/
private function getPrivateKey()
{
$original_private_key = $this->private_key;
return openssl_pkey_get_private($original_private_key);
}
/**
* 配置公钥
* openssl_pkey_get_public这个函数可用来判断私钥是否是可用的,可用,返回资源
* @return resource
*/
public function getPublicKey()
{
$original_public_key = $this->public_key;
return openssl_pkey_get_public($original_public_key);
}/**
* 生成签名
* @param string $signString 待签名字符串
* @return string base64结果值
* OPENSSL_ALGO_DSS1
* OPENSSL_ALGO_SHA1
* OPENSSL_ALGO_SHA224
* OPENSSL_ALGO_SHA256
* OPENSSL_ALGO_SHA384
* OPENSSL_ALGO_SHA512
* OPENSSL_ALGO_RMD160
* OPENSSL_ALGO_MD5
* OPENSSL_ALGO_MD4
* OPENSSL_ALGO_MD2
*/
public function getSign($signString){
$signature = '';
$this->private_key = $this->formatPriKey(config('tongue.rsa_devprivate_key'));
$this->private_key = $this->getPrivateKey();
openssl_sign($signString, $signature, $this->private_key,OPENSSL_ALGO_MD5);
return base64_encode($signature);
}7、rsa签名验签(使用公钥验签)
/**
* 校验签名
* @param string $sign 签名
* @param string $toSign 待签名字符串
* OPENSSL_ALGO_DSS1
* OPENSSL_ALGO_SHA1
* OPENSSL_ALGO_SHA224
* OPENSSL_ALGO_SHA256
* OPENSSL_ALGO_SHA384
* OPENSSL_ALGO_SHA512
* OPENSSL_ALGO_RMD160
* OPENSSL_ALGO_MD5
* OPENSSL_ALGO_MD4
* OPENSSL_ALGO_MD2
* @return bool
*/
function checkSign($sign,$toSign){
$re = $this->formatPubKey(config('tongue.rsa_companypublic_key'));
$re = openssl_pkey_get_public($re);
$result = openssl_verify($toSign, base64_decode($sign), $re,OPENSSL_ALGO_MD5);
return $result === 1 ? true : false;
}8、JWT加密&签名验证(简单的PHP示例),详情可参考JWT官网:https://jwt.io
与jwt官网中的base64UrlEncode中对应的php的实现方法为
/**
* base64UrlEncode https://jwt.io/ 中base64UrlEncode编码实现
* @param string $input 需要编码的字符串
* @return string
*/
private static function base64UrlEncode(string $input)
{
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}与jwt官网中的base64UrlEncode中对应的php的实现方法为
/**
* base64UrlEncode https://jwt.io/ 中base64UrlEncode解码实现
* @param string $input 需要解码的字符串
* @return bool|string
*/
private static function base64UrlDecode(string $input)
{
$remainder = strlen($input) % 4;
if ($remainder) {
$addlen = 4 - $remainder;
$input .= str_repeat('=', $addlen);
}
return base64_decode(strtr($input, '-_', '+/'));
}$header,$payload,$secret 3个参数分别如下
$header['alg'] = 'HS256'; $header['typ'] = 'JWT'; $payload['sub'] = '1234567890'; $payload['name'] = 'John!~#423▼Doe'; $payload['iat'] = 1516239022; $secret = '123456';
jwt加密后的值为
$re = hash_hmac( 'sha256', $this->base64UrlEncode(json_encode($header,JSON_UNESCAPED_UNICODE)) . "." . $this->base64UrlEncode(json_encode($payload,JSON_UNESCAPED_UNICODE)), $secret, true );
打印后对比官网的值,一致
print_dump($this->base64UrlEncode(json_encode($header,JSON_UNESCAPED_UNICODE)) . "." . $this->base64UrlEncode(json_encode($payload,JSON_UNESCAPED_UNICODE)) . "." . $this->base64UrlEncode($re));die;
注意:若官网中勾选“secret base64 encoded”选项,表示官网中secret的值要填base64加密后的值(最好用base64UrlEncode方法加密的而不是用php的base64_encode加密的,即这里的private static function base64UrlEncode方法),即例如此php例子中$secret = '123456',则官网中若勾选“secret base64 encoded”后填入的值为'MTIzNDU2',加密的结果一致
另:jwt的其他加密方法入HS384等,均与此类似
9、js、c#与php公用的aes加密解密方式,详情可参考https://www.cnblogs.com/zjbky/p/6065829.html
先设置好key,iv,以及待加密的字符串str
$key = "zhimeikm ";
$iv = "1234567812345678";
$str = '{"d":"211022151725","u":"klfjeioadnfg"}';
$str_padded = '{"d":"211022151725","u":"klfjeioadnfg"}';因为使用OPENSSL_NO_PADDING方式,所以待加密的字符串为16个字,不够的话要填充零
if (strlen($str) % 16) {
$str = str_pad($str,strlen($str) + 16 - strlen($str) % 16, "\0");
}加密的结果为
$en_data = base64_encode(openssl_encrypt($str, "AES-256-CBC", $key, OPENSSL_NO_PADDING, $iv)); print_dump($en_data); print_dump(openssl_error_string());
解密时,需要注意去除填充的零(貌似不去除也没问题)
$de_data = openssl_decrypt(base64_decode($en_data), "AES-256-CBC", $key, OPENSSL_NO_PADDING, $iv); print_dump(rtrim($de_data)); // 一般情况下rtrim一下即可得到想要的结果,无需以下的chr(0),chr(7)截取 print_dump( rtrim( rtrim( $de_data,chr(0) ), chr(7) ) ); print_dump(openssl_error_string());