Api 签名算法

描述

为了保证第三方应用与API服务器之间通信的安全性,防止SecretKey盗用、数据篡改等恶意攻击行为,开放平台API服务器使用签名机制,应用在调用开放平台API,需要计算出一个签名。

请求发起方式

通过页面中的JavaScript、Flash内的actionScript或手机、桌面客户端程序发起。则签名是由请求参数和SessionSecret(每个用户的SessionKey所对应的密钥)经过指定的加密算法生成的字符串。

签名是由请求参数和应用的私钥经过对应加密算法生成的。

签名的生成

不生成签名的情况也是存在,例如web站点开发前后端分离。但是由于基于session的特性,可以支持正常的业务处理,不过要进行一些必要的准备。

登陆验证

采用post方式提交数据

构造token令牌,例如md5(uniqid(rand(),TRUE)),可以设置失效时间

验证referer,同源策略规划

Api授权

等等

请求增加key和sign参数,解决身份验证和防止参数篡改问题,私钥不要外泄。

分配对应的key、secret

签名生成规则

请求参数新增时间戳timestamp,可以验证请求是否过期。

$secret作加密使用,为了保证数据安全,不要在请求参数中体现。

升级优化

对于安全相对高点的系统来讲,签名会采用自己指定的复杂规则,header,body都会做相应处理。例如企业报文,电子订单信息等。

数据加密/编码算法列表

参考:

密钥算法用来对敏感数据、摘要、签名等信息进行加密,常用的密钥算法包括:

DES(DataEncryptionStandard):数据加密标准,速度较快,适用于加密大量数据的场合;

3DES(TripleDES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高;

RC2和RC4:用变长密钥对大量数据进行加密,比DES快;

IDEA(InternationalDataEncryptionAlgorithm)国际数据加密算法,使用128位密钥提供非常强的安全性;

RSA:由RSA公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件快的长度也是可变的;

DSA(DigitalSignatureAlgorithm):数字签名算法,是一种标准的DSS(数字签名标准);

AES(AdvancedEncryptionStandard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前AES标准的一个实现是Rijndael算法;

BLOWFISH,它使用变长的密钥,长度可达448位,运行速度很快;

其它算法,如ElGamal、Deffie-Hellman、新型椭圆曲线算法ECC等。

单向散列函数一般用于产生消息摘要,密钥加密等,常见的有:

MD5(MessageDigestAlgorithm5):是RSA数据安全公司开发的一种单向散列算法,MD5被广泛使用,可以用来把不同长度的数据块进行暗码运算成一个128位的数值;

SHA(SecureHashAlgorithm)这是一种较新的散列算法,可以对任意长度的数据运算生成一个160位的数值;

MAC(MessageAuthenticationCode):消息认证代码,是一种使用密钥的单向函数,可以用它们在系统上或用户之间认证文件或消息。HMAC(用于消息认证的密钥散列法)就是这种函数的一个例子。

CRC(CyclicRedundancyCheck):循环冗余校验码,CRC校验由于实现简单,检错能力强,被广泛使用在各种数据校验应用中。占用系统资源少,用软硬件均能实现,是进行数据传输差错检测地一种很好的手段(CRC并不是严格意义上的散列算法,但它的作用与散列算法大致相同,所以归于此类)。

其它数据算法包括一些常用编码算法及其与明文(ASCII、Unicode等)转换等,如Base64、QuotedPrintable、EBCDIC等。

示例代码,仅供参考:
/***签名生成算法*@paramarray$paramsAPI调用的请求参数集合的关联数组,不包含sign参数*@returnstring返回参数签名值*/functiongetSignature($params,$secret){$str='';ksort($params);foreach($paramsas$k=$v){$str.="$k=$v";}$str.=$secret;returnmd5($str);}
/**生成签名,$args为请求参数,$key为私钥*/functionmakeSignature($args,$key){if(isset($args['sign'])){$oldSign=$args['sign'];unset($args['sign']);}else{$oldSign='';}ksort($args);$requestString='';foreach($argsas$k=$v){$requestString.=$k.'='.urlencode($v);}$newSign=hash_hmac("md5",strtolower($requestString),$key);return$newSign;}
?php/***数据加密解密使用*/header("Content-type:text/html;charset=utf-8");ini_set('','Asia/Shanghai');classRsa{public$pubkey;public$privkey;function__construct($pubkey='',$privkey=''){$this-pubkey=$pubkey;$this-privkey=$privkey;}/**加密**/publicfunctionencrypt($data){if(empty($data)){returnnull;}$pem="-----BEGINPUBLICKEY-----\n".chunk_split($this-pubkey,64,"\n")."-----ENDPUBLICKEY-----\n";$key=openssl_pkey_get_public($pem);$resultb="";$dataArray=str_split($data,117);foreach($dataArrayas$d){if(openssl_public_encrypt($d,$encrypted,$key)){$resultb.=$encrypted;}elsereturnnull;}returnbase64_encode($resultb);}/**解密**/publicfunctiondecrypt($data){$pem="-----BEGINPRIVATEKEY-----\n".chunk_split($this-privkey,64,"\n")."-----ENDPRIVATEKEY-----\n";$key=openssl_pkey_get_private($pem);$resultb="";$dataArray=str_split(base64_decode($data),128);foreach($dataArrayas$d){if(openssl_private_decrypt($d,$encrypted,$key)){$resultb.=$encrypted;}elsereturnnull;}return$resultb;}/**数字签名**/publicfunctionmd5($data){$xtt=urlencode(base64_encode(md5($data)));//数字签名return$xtt;}}
?php/***CRC16-CCITTvalidator*ClassCRC*/classCRC{private$crc_table=array(0x0,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,0x1231,0x210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,0x2462,0x3443,0x420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,0x3653,0x2672,0x1611,0x630,0x76d7,0x66f6,0x5695,0x46b4,0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,0x48c4,0x58e5,0x6886,0x78a7,0x840,0x1861,0x2802,0x3823,0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0xa50,0x3a33,0x2a12,0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0xc60,0x1c41,0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0xe70,0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,0x1080,0xa1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,0x2b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,0x34e2,0x24c3,0x14a0,0x481,0x7466,0x6447,0x5424,0x4405,0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,0x26d3,0x36f2,0x691,0x16b0,0x6657,0x7676,0x4615,0x5634,0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,0x5844,0x4865,0x7806,0x6827,0x18c0,0x8e1,0x3882,0x28a3,0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,0x4a75,0x5a54,0x6a37,0x7a16,0xaf1,0x1ad0,0x2ab3,0x3a92,0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0xcc1,0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0xed1,0x1ef0);functiongenCRC($ptr){$crc=0x0000;for($i=0;$istrlen($ptr);$i++)$crc=$this-crc_table[(($crc8)^ord($ptr[$i]))]^(($crc8)0x00FFFF);$ret=sprintf('%02x%02x',floor($crc/256),$crc%256);returnstrtoupper($ret);}}
?php/***ClassDES*/classDES{var$key;var$iv;functionDES($key,$iv){$this-key=$key;$this-iv=$iv;}functionencrypt($str){$size=mcrypt_get_block_size(MCRYPT_DES,MCRYPT_MODE_CBC);$str=$this-pkcs5Pad($str,$size);//echo$size.'br';//echo$str."br";//echo$this-key.'br';//echo$this-iv.'br';//returnmcrypt_cbc(MCRYPT_DES,$this-key,$str,MCRYPT_ENCRYPT,$this-iv);$cipher=mcrypt_module_open(MCRYPT_DES,'','cbc','');mcrypt_generic_init($cipher,$this-key,$this-iv);returnmcrypt_generic($cipher,$str);}functiondecrypt($str){$strBin=$str;//$str=mcrypt_cbc(MCRYPT_DES,$this-key,$strBin,MCRYPT_DECRYPT,$this-iv);$cipher=mcrypt_module_open(MCRYPT_DES,'','cbc','');mcrypt_generic_init($cipher,$this-key,$this-iv);$str=mdecrypt_generic($cipher,$str);$str=$this-pkcs5Unpad($str);return$str;}functionpkcs5Unpad($text){$pad=ord($text{strlen($text)-1});if($padstrlen($text))returnfalse;if(strspn($text,chr($pad),strlen($text)-$pad)!=$pad)returnfalse;returnsubstr($text,0,-1*$pad);}functionpkcs5Pad($text,$blocksize){$pad=$blocksize-(strlen($text)%$blocksize);return$_repeat(chr($pad),$pad);}}classSaaSSafe{private$iv;functionset_iv($i){if($i!=''){$this-iv=$i;}}publicfunctionEncode($o_string){$md5_string=md5($o_string);$body_string=$md5_string.$o_string;$key=$this-makeKey($this-iv);$des_body_string=$this-desEn($body_string,$this-iv,$key);$ret=base64_encode($des_body_string);return$ret;}publicfunctionDecode($o_string){$de_base_string=base64_decode($o_string);$key=$this-makeKey($this-iv);$de_des_string=$this-desDe($de_base_string,$this-iv,$key);$ret=substr($de_des_string,32);return$ret;}functionodd($o_string){$ret='';for($i=0;$istrlen($o_string);$i++){if($i%2==0){$ret.=substr($o_string,$i,1);}}return$ret;}functionmakeKey($iv){if($iv!=''){return$this-odd(substr(md5($iv),8,16));}}privatefunctiondesEn($o_string,$iv,$key){$des=newDES($key,$iv);$ret=$des-encrypt($o_string);return$ret;}privatefunctiondesDe($o_string,$iv,$key){$des=newDES($key,$iv);$ret=$des-decrypt($o_string);return$ret;}}
/*参考:;mid=2448834812idx=1sn=d27c9478b98a184acdb8ca7e9fbfc751chksm=b28a403c85fdc92aca0461556ee3b1114bbf43fe630baeb0a61f72187dcd6d355018baa1f82b#rd*/classRsa2{privatestatic$PRIVATE_KEY='rsa_private_内容';privatestatic$PUBLIC_KEY='rsa_public_内容';/***获取私钥*@returnbool|resource*/privatestaticfunctiongetPrivateKey(){$privKey=self::$PRIVATE_KEY;returnopenssl_pkey_get_private($privKey);}/***获取公钥*@returnbool|resource*/privatestaticfunctiongetPublicKey(){$publicKey=self::$PUBLIC_KEY;returnopenssl_pkey_get_public($publicKey);}/***创建签名*@paramstring$data数据*@returnnull|string*/publicfunctioncreateSign($data=''){if(!is_string($data)){returnnull;}returnopenssl_sign($data,$sign,self::getPrivateKey(),OPENSSL_ALGO_SHA256)?base64_encode($sign):null;}/***验证签名*@paramstring$data数据*@paramstring$sign签名*@returnbool*/publicfunctionverifySign($data='',$sign=''){if(!is_string($sign)||!is_string($sign)){returnfalse;}return(bool)openssl_verify($data,base64_decode($sign),self::getPublicKey(),OPENSSL_ALGO_SHA256);}}

补充:byte数组与字符串转化类

?php/***byte数组与字符串转化类*/classBytes{/***转换一个String字符串为byte数组*@param$str需要转换的字符串*@param$bytes目标byte数组*@authorZikie*/publicstaticfunctiongetBytes($str){$len=strlen($str);$bytes=array();for($i=0;$i$len;$i++){if(ord($str[$i])=128){$byte=ord($str[$i])-256;}else{$byte=ord($str[$i]);}$bytes[]=$byte;}return$bytes;}/***将字节数组转化为String类型的数据*@param$bytes字节数组*@param$str目标字符串*@return一个String类型的数据*/publicstaticfunctiontoStr($bytes){$str='';foreach($bytesas$ch){$str.=chr($ch);}return$str;}/***转换一个int为byte数组*@param$byt目标byte数组*@param$val需要转换的字符串*@authorZikie*/publicstaticfunctionintegerToBytes($val){$byt=array();$byt[0]=($val0xff);$byt[1]=($val80xff);$byt[2]=($val160xff);$byt[3]=($val240xff);return$byt;}/***从字节数组中指定的位置读取一个Integer类型的数据*@param$bytes字节数组*@param$position指定的开始位置*@return一个Integer类型的数据*/publicstaticfunctionbytesToInteger($bytes,$position){$val=0;$val=$bytes[$position+3]0xff;$val=8;$val|=$bytes[$position+2]0xff;$val=8;$val|=$bytes[$position+1]0xff;$val=8;$val|=$bytes[$position]0xff;return$val;}/***转换一个shor字符串为byte数组*@param$byt目标byte数组*@param$val需要转换的字符串*@authorZikie*/publicstaticfunctionshortToBytes($val){$byt=array();$byt[0]=($val0xff);$byt[1]=($val80xff);return$byt;}/***从字节数组中指定的位置读取一个Short类型的数据。*@param$bytes字节数组*@param$position指定的开始位置*@return一个Short类型的数据*/publicstaticfunctionbytesToShort($bytes,$position){$val=0;$val=$bytes[$position+1]0xFF;$val=$val8;$val|=$bytes[$position]0xFF;return$val;}}?
发布于 2025-01-27
26
目录

    推荐阅读