PHP署名検証のhash_hmac sha1
前言
1.secret_の生成key
2.署名の生成
3.署名照合
4.サイト検証(sha 1.html)
5.コード
5.1 HashHmacSha1.php
5.2 sha1.html
6.テスト
7.sha1.html実行参照
読んでくれてありがとう!
secret_id: Id
secret_key: Key
SHA1:
hash_hmac: php hash
hash_hmac_file:
1.secret_の生成key
hash_hmac_file('SHA1','signature.txt','secret');
2.署名の生成
base64_encode(hash_hmac('SHA1', $init, $secret_key, true).$init);
3.署名照合
base64_decode($initSign);
base64_encode(hash_hmac('SHA1', $init, $secret_key, true).$init);
4.サイト検証(sha 1.html)
sha1.html
5.コード
5.1 HashHmacSha1.php
code;
}
/** message
* @return string
*/
public function getMessage()
{
return $this->message;
}
/** , 32
* @param int $length
* @return string
*/
public function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789!@#%^&*;:-=_+,.";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
/** sha1 secret
* @other ,secret_key,secret_id
* @return string
*/
public function signSha1Create()
{
$nonce = $this->getNonceStr();
$rand = rand();
$time = time();
$content = "The signature : nonce={$nonce}; rand={$rand}; time={$time}, by sok yo!";
//
file_put_contents('signature.txt', $content);
$signature = hash_hmac_file('SHA1','signature.txt','secret');
unlink('signature.txt');
return $signature;
}
/** sha1
* @param $secret_id
* @param $secret_key
* @return string
*/
public function signSha1Encrypt($secret_id,$secret_key)
{
$time = time();
// , ( )
$arg_list = array(
"secretId" => $secret_id,
"currentTimeStamp" => $time,
"expireTime" => $time+86400,
"random" =>rand(),
);
$init = http_build_query($arg_list);
//
// raw_output = false ; 53e55273e57c3cf6b7c16e5840479566be3aa0d2,16 (40 )
// raw_output = true ; �� Ej���۔����̠��, (20 )
// base64_encode 8-bit ( )。
// base64_encode 33% 。
$signature = base64_encode(hash_hmac('SHA1', $init, $secret_key, true).$init);
// JS CryptoJS
return $signature ;
}
/** sha1
* @param $initSign
* @param $secretId
* @param $secretKey
* @return bool
*/
public function signSha1Decrypt($initSign,$secretId,$secretKey)
{
// base64 ,
$sign = base64_decode($initSign);
// 5 sha1 , : +16 (0041),5 = 5 * 4( ) = 20( )
$signStr = substr($sign,20);
//
parse_str($signStr,$signArr);
// ( )
$mustKey = ['secretId','currentTimeStamp','expireTime','random'];
foreach ($mustKey as $k) {
if(!isset($signArr[$k])) {
$this->code = 400;
$this->message = 'miss '.$k;
return false;
}
}
//secretId
if((string)$signArr['secretId'] !== (string)$secretId) {
$this->code = 400;
$this->message = 'error secretId';
return false;
}
//
if($signArr['currentTimeStamp'] > $signArr['expireTime']) {
$this->code = 400;
$this->message = 'error currentTimeStamp';
return false;
}
//
if($signArr['expireTime'] < time()) {
$this->code = 400;
$this->message = 'expireTime expired';
return false;
}
//
$signature = base64_encode(hash_hmac('SHA1', $signStr, $secretKey, true).$signStr);
if($signature === $initSign) {
$this->code = 200;
$this->message = 'success';
return true;
}else{
$this->code = 400;
$this->message = 'error signature';
return false;
}
}
}
5.2 sha1.html
hash_hmac sha1
hash_hmac sha1
var signature,secret_key;
$("#decodeSig").click(function(){
signature = $("input[name=signature]").val();
if(!signature) {
alert(' ');
} else {
var signature = $("input[name=signature]").val();
decodeSignature(signature);
}
});
$("#checkSecretkey").click(function(){
signature = $("input[name=signature]").val();
secret_key = $("input[name=secretKey]").val();
var checkResult;
if(!secret_key) {
$("input[name=decodeResult]").val('Secret Key ');
} else {
checkResult = check(signature, secret_key);
if(checkResult){
if(checkResult == 'expired') {
$("input[name=decodeResult]").val(' ');
} else if(checkResult == 'notInt') {
$("input[name=decodeResult]").val(' ');
} else if (checkResult == 'wrongExpireTime') {
$("input[name=decodeResult]").val('expireTime currentTimeStamp');
} else {
$("input[name=decodeResult]").val(' ');
}
}else {
$("input[name=decodeResult]").val(' ');
}
}
});
var decodeSignature = function(signature){
// var sha = CryptoJS.HmacSHA1(argStr, secret_key);
// sha.concat(CryptoJS.enc.Utf8.parse(argStr))
// var signature = CryptoJS.enc.Base64.stringify(sha);
$(".non-required-form").hide();
$(".required-form .form-value").val("");
$("input[name=queryString]").val("");
var queryString = getOriginalStr(signature);
// input
$("input[name=queryString]").val(queryString);
var arr = queryString.split("&");
arr.map(function(item){
var name = item.split("=")[0].replace(/\./,"_");
var value = decodeURIComponent(item.split("=")[1]);
if(!name || !value) {
alert(' , ');
return;
}
var input = $("input[name='"+escape(name)+"']");
if(input.length>=1){
$(input).val(value);
$(input).closest(".non-required-form").show();
if (name === 'currentTimeStamp') {
$('.currentTimeStampHuman').text(new Date(value * 1000))
}
if (name === 'expireTime') {
$('.expireTimeHuman').text(new Date(value * 1000))
}
}else{
var customInput = '<div class="form-group form-inline non-required-form" style="display:block">'
+ '<label class="col-sm-3 control-label"></label>'
+ '<div class="col-sm-9">'
+ '<input type="text" class="form-control form-name" disabled>'
+ '<input type="text" class="form-control form-value" disabled>'
+ '</div></div>';
$(".required-form:last").after(customInput);
$(".required-form:last").next().find('.form-name').val(name);
$(".required-form:last").next().find('.form-value').val(value);
}
})
}
function getOriginalStr(signature) {
var buffer = CryptoJS.enc.Base64.parse(signature);
var argBuffer = CryptoJS.lib.WordArray.create(buffer.words.slice(5), buffer.sigBytes-20);
return argBuffer.toString(CryptoJS.enc.Utf8);
}
function check(signature, secret_key) {
// base64 , buffer
var buffer = CryptoJS.enc.Base64.parse(signature);
// 5 sha1
var shaBuffer = CryptoJS.lib.WordArray.create(buffer.words.slice(0, 5), 20);
// 5 querystring, UTF8
var argBuffer = CryptoJS.lib.WordArray.create(buffer.words.slice(5), buffer.sigBytes-20);
// querystring UTF8 buffer string
var argStr = argBuffer.toString(CryptoJS.enc.Utf8);
// sk + querystring sha
var sha = CryptoJS.HmacSHA1(argStr, secret_key);
// sha
if(!$("input[name=expireTime]").val()) {
decodeSignature(signature);
}
if(+$("input[name=currentTimeStamp]").val() > +$("input[name=expireTime]").val()) {
return 'wrongExpireTime';
}
//
if(+$("input[name=expireTime]").val() < Math.floor((+new Date())/1000)) {
return 'expired';
}
if(isNaN($("input[name=random]").val()) || isNaN($("input[name=currentTimeStamp]").val()) || isNaN($("input[name=expireTime]").val())) {
return 'notInt';
}
return sha.toString(CryptoJS.enc.Base64) === shaBuffer.toString(CryptoJS.enc.Base64);
}
var _mtac = {};
(function() {
var mta = document.createElement("script");
mta.src = "https://pingjs.qq.com/h5/stats.js?v2.0.2";
mta.setAttribute("name", "MTAH5");
mta.setAttribute("sid", "500428027");
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(mta, s);
})();
6.テスト
//
$model = new HashHmacSha1();
// secret_id
$secretId = 'abc1234Def453';
// secret_key
$secretKey = $model->signSha1Create();
//'fe08bd195744e08e289174167b1d53cd638e6f7b';
//
$sign = $model->signSha1Encrypt($secretId,$secretKey);
//'ZQlqVb8DKt14kDD6TCxWQMQARVxzZWNyZXRJZD1hYmMxMjM0RGVmNDUzJmN1cnJlbnRUaW1lU3RhbXA9MTU2Njg4NzA2MyZleHBpcmVUaW1lPTE1NjY5NzM0NjMmcmFuZG9tPTk4MTEzNjMwNA==';
//
$res = $model->signSha1Decrypt($sign,$secretId,$secretKey);
var_dump($res);
7.sha1.html実行参照
読んでくれてありがとう!