请教大神请赐教,支付宝回调的时候,签名长度不对怎么解决

支付宝签名不一致的问题
我的图书馆
支付宝签名不一致的问题
斑竹:bodies
ly123 (ly123)
▲▲▲▲▲
盒子活跃会员
支付宝签名不一致的问题
浏览:<font color="#99
Delphi2007,从网上找来的这样两个函数function&TMainForm.LoadPrivateKey(filename:string&):&PEVP_PKEY;var&bp:&PBIO;&&A,&pkey:&PEVP_PKEY;begin&&a:=&&bp&:=&BIO_new(BIO_s_file())&;&&BIO_read_filename(bp,&PChar(filename));&&pkey&:=&PEM_read_bio_PrivateKey(bp,&a,&nil,NIL);&&BIO_free(bp);&&Result:=&function&TMainForm.Sign(filename:&&msg:&String):&Svar&ctx:&EVP_MD_CTX;&&buf_in:&PAnsiC&&m_len,&outl:&&&pkey:&PEVP_PKEY;&&m,&buf_out:&array&[0..1024]&of&AnsiC&&p:&array&[0..255]&of&AnsiC&&i:&Ibegin&&buf_out&:=&'';&&if&filename&=&''&then&&begin&&&&Result&:=&'';&&&&E&&&&pKey&:=&LoadPrivateKey(filename);&&buf_in&:=&PAnsiChar(msg);&&EVP_MD_CTX_init(@ctx);&&&&&&&&&&//初始化&&EVP_SignInit(@ctx,EVP_sha1());&&&&//将需要使用的摘要算法存入ctxl中&&EVP_SignUpdate(@ctx,buf_in,Length(buf_in));//存入编码值&&EVP_DigestFinal(@ctx,m,m_len);&&&&//求取编码的长度为m_len摘要值存入m中&&RSA_sign(EVP_sha1()._type,m,m_len,buf_out,@outl,pkey.pkey.rsa);&//64为SHA1的NID&&EVP_MD_CTX_cleanup(@ctx);&&Result&:=&EncodeString(StrPas(buf_out));和对应的libeay32.pas、libeay32.dll和ssleay32.dll,并在libeay32.pas中添加了相应的函数,把Indy升级到10.5.8,现在可以计算签名了,问题是有的字符串能计算对,有的字符串计算不对,对与错的比例在7:3左右,并且错的字符串和对的字符串前边的字符是完全一样的,只是错的字符串比对的字符串要短一些。如:对的是mmfA7WgjdfS6xy2mJzXydNsrL8Z9cmLXDpV5YkVDl2ZLsWl22qkomrKnLmyP+/du0lyBE034OqgwaXURQ5HWUBl/qa2xafUW1EzFTIK5VXO59fI1gwBnyNS9hbjfUriWPsMGDWEeNyZs57L9nTa7IMmlGjrXwXJWpStl59jrf2w=错的是mmfA7WgjdfS6xy2mJzXydNsrL8Z9cmLXDpV5YkVDl2ZLsWl22qkomrKnLmyP+/du0lyBE034OqgwaXURQ5HWUBl/qa2xafUW1EzFTIK5VXO59fI1gw==初步分析应该是编码的问题,可是把要签名的字符串赋值给memo或者写到文件中再取出来都解决不了这种问题,有没有人遇到类似的情况呢
----------------------------------------------
ly123 (ly123)
▲▲▲▲▲
盒子活跃会员
<font color="#楼:
签名对的截图
此帖子包含附件: 大小:245.5K
----------------------------------------------
ly123 (ly123)
▲▲▲▲▲
盒子活跃会员
<font color="#楼:
签名不对的截图
此帖子包含附件: 大小:205.9K
----------------------------------------------
olddelphier (oldDelphier)
▲▲△△△
<font color="#楼:
用那个dll,签名不对经常遇到同样的程序,大概1/3的机会,不知道原因我是循环调用,直到遇到签名正确的
----------------------------------------------
ly123 (ly123)
▲▲▲▲▲
盒子活跃会员
<font color="#楼:
谢谢回复!我发现与需要签名的字符串有关,如果某个字符串的签名能计算对,则每次计算都是对的,也就是说同一个字符串每次计算出来的结果都是一样的
----------------------------------------------
olddelphier (oldDelphier)
▲▲△△△
<font color="#楼:
同样的字符集串,计算结果是一样的,不管签名正确或不正确签名不正确,其他不变,就把timestamp修改一下,重新计算,就有可能正确了
----------------------------------------------
letianwuji (乐天无极)
▲▲△△△
<font color="#楼:
问题核心:1,是否存在提交跟上一次内容一致的内容比如,随机函数,是可以两次都是2的,严格算伪随机算法;2,时区判定像时间戳的验证,多少为了基于地域安全判定——主要是跨国业务通常会时间戳审核一次时间区3,字符编码有些函数的编码,对某些字符-单字节与双字节处理是有差异的。遇到过AS3能识别的json,而用delphi直接提示有非法字符。
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
letianwuji (乐天无极)
▲▲△△△
<font color="#楼:
目测,可能是+/&一类的非字母字符引发的。
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
olddelphier (oldDelphier)
▲▲△△△
<font color="#楼:
支付宝客户的答复:没有delphi程序员,没有delphi例程,也没人懂delphi自己找原因那么大一个公司,外包找人写个demo难道要很多钱吗?
----------------------------------------------
ly123 (ly123)
▲▲▲▲▲
盒子活跃会员
<font color="#楼:
Delphi自从在2003年在国内的使用人数达到顶峰以后就开始每况愈下了,眼下还使用Delphi的估计绝大多数都是Old&Delphier了,Delphi虽然新版本不断,但是却再也达不到以前辉煌的程度了,以前总是说聪明的程序员用Delphi.现在也不知道聪明的程序员用什么了谢谢olddelphier,我决定暂时也使用您的那种方案,用一个二重循环来解决,一个是生成签名后先判断一下签名的长度,如果小于172就重新生成交易字符串和签名,如果支付宝返回无效的签名,就把整个过程重做一遍直到成功出现这种问题的原因应该是libeay32.dll中的函数有缺陷,Delphi这种签名方法还只有0.9.8版的支持这种方法,返回的签名也不能直接用,需要赋值给memo,在通过memo.lines[0]+memo.lines[1]+memo.lines[2]得到的才可以用
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
&uses&IdHMACSHA1,IdG用TIdHMACSHA1看看,这个签名算法Indy10实现了得.
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
XE8&下可以用System.Hash原生支持.
----------------------------------------------
delphiteacher (delphiteacher)
▲▲△△△
<font color="#楼:
我在做IOS的支付宝支付的时候,也需要用到RSA签名,用的是SSL里面的函数,没问题
----------------------------------------------
欢迎访问我的博客:
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
openssl也是原生支持HMACSHA1的.
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
这个例子更简单
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
IdSSLOpenSSLHeaders
----------------------------------------------
ly123 (ly123)
▲▲▲▲▲
盒子活跃会员
<font color="#楼:
谢谢各位的支持!有些代码在Delphi2007下运行不了,上午修改了EncdDecd.pas中的procedure&EncodeStream(Input,&Output:&TStream);屏蔽掉了一小段代码,现在签名可以直接使用了procedure&EncodeStream(Input,&Output:&TStream);type&&PInteger&=&^Ivar&&InBuf:&array[0..509]&of&B&&OutBuf:&array[0..1023]&of&C&&BufPtr:&PC&&I,&J,&K,&BytesRead:&I&&Packet:&TPbegin&&K&:=&0;&&repeat&&&&BytesRead&:=&Input.Read(InBuf,&SizeOf(InBuf));&&&&I&:=&0;&&&&BufPtr&:=&OutB&&&&while&I&&&BytesRead&do&&&&begin&&&&&&if&BytesRead&-&I&&&3&then&&&&&&&&J&:=&BytesRead&-&I&&&&&&else&J&:=&3;&&&&&&Packet.i&:=&0;&&&&&&Packet.b0&:=&InBuf[I];&&&&&&if&J&&&1&then&&&&&&&&Packet.b1&:=&InBuf[I&+&1];&&&&&&if&J&&&2&then&&&&&&&&Packet.b2&:=&InBuf[I&+&2];&&&&&&EncodePacket(Packet,&J,&BufPtr);&&&&&&Inc(I,&3);&&&&&&Inc(BufPtr,&4);&&&&&&Inc(K,&4);&&&&&&{if&K&&&75&then&&&//&&&&&&&begin&&&&&&&&BufPtr[0]&:=&#$0D;&&&&&&&&BufPtr[1]&:=&#$0A;&&&&&&&&Inc(BufPtr,&2);&&&&&&&&K&:=&0;&&&&&&}&&&//&&&&&&&&&Output.Write(Outbuf,&BufPtr&-&PChar(@OutBuf));&&until&BytesRead&=&0;现在遇到的问题是出错的签名比和正确的签名长度短,出错签名中的字符和正确签名中的是完全一样的.TO&delphiteacher:能不能把您使用的libeay32.dll和ssleay32.dll这两个文件发给我试一下呢&QQ:
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
找到一个纯delphi实现的./fundamentalslib/fundamentals5.git在flcHash.pas里实现了HMACSHA1
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
楼主你的函数是不正确的.
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
这是windows&API版.function&Hashhmacsha1(const&Key,&Value:&AnsiString):&AnsiSconst&&KEY_LEN_MAX&=&16;var&&hCryptProvider:&HCRYPTPROV;&&hHash:&HCRYPTHASH;&&hKey:&HCRYPTKEY;&&bHash:&array[0..$7F]&of&B&&dwHashLen:&dW&&i:&I&&hPubKey&:&HCRYPTK&&hHmacHash:&HCRYPTHASH;&&bHmacHash:&array[0..$7F]&of&B&&dwHmacHashLen:&dW&&hmac_info&:&Wcrypt2.HMAC_INFO;&&keyBlob:&record&&&&keyHeader:&BLOBHEADER;&&&&keySize:&DWORD;&&&&keyData:&array[0..KEY_LEN_MAX-1]&of&B&&&&keyLen&:&INTEGER;begin&&dwHashLen&:=&32;&&dwHmacHashLen&:=&32;&&{get&context&for&crypt&default&provider}&&if&CryptAcquireContext(@hCryptProvider,&nil,&nil,&PROV_RSA_FULL,&CRYPT_VERIFYCONTEXT)&then&&begin&&&&{create&hash-object&MD5}&&&&if&CryptCreateHash(hCryptProvider,&CALG_SHA1,&0,&0,&@hHash)&then&&&&begin&&&&&&{get&hash&from&password}&&&&&&if&CryptHashData(hHash,&PByte(Key),&Length(Key),&0)&then&&&&&&begin&&&&&&&&//&hHash&is&now&a&hash&of&the&provided&key,&(SHA1)&&&&&&&&//&Now&we&derive&a&key&for&it&&&&&&&&hPubKey&:=&0;&&&&&&&&FillChar(keyBlob,&SizeOf(keyBlob),&0);&&&&&&&&keyBlob.keyHeader.bType&:=&PLAINTEXTKEYBLOB;&&&&&&&&keyBlob.keyHeader.bVersion&:=&CUR_BLOB_VERSION;&&&&&&&&keyBlob.keyHeader.aiKeyAlg&:=&CALG_RC4;&&&&&&&&KeyBlob.keySize&:=&KEY_LEN_MAX;&&&&&&&&if(Length(key)&&&(KEY_LEN_MAX))then&&&&&&&&&&KeyLen&:=&Length(key)&&&&&&&&else&&&&&&&&&&KeyLen&:=&KEY_LEN_MAX;&&&&&&&&Move(Key[1],&KeyBlob.keyData[0],&KeyLen&);&&&&&&&&if&CryptImportKey(hCryptProvider,&@keyBlob,&SizeOf(KeyBlob),&hPubKey,&0,&@hKey)&then&&&&&&&&begin&&&&&&&&&&//hkey&now&holds&our&key.&So&we&have&do&the&whole&thing&over&again&&&&&&&&&&ZeroMemory(&@hmac_info,&SizeOf(hmac_info)&);&&&&&&&&&&hmac_info.HashAlgid&:=&CALG_SHA1;&&&&&&&&&&if&CryptCreateHash(hCryptProvider,&CALG_HMAC,&hKey,&0,&@hHmacHash)&then&&&&&&&&&&begin&&&&&&&&&&if&CryptSetHashParam(&hHmacHash,&HP_HMAC_INFO,&@hmac_info,&0)&then&&&&&&&&&&begin&&&&&&&&&&if&CryptHashData(hHmacHash,&@Value[1],&Length(Value),&0)&then&&&&&&&&&&begin&&&&&&&&&&if&CryptGetHashParam(hHmacHash,&HP_HASHVAL,&@bHmacHash[0],&@dwHmacHashLen,&0)&then&&&&&&&&&&begin&&&&&&&&&&for&i&:=&0&to&dwHmacHashLen-1&do&&&&&&&&&&Result&:=&Result&+&IntToHex(bHmacHash[i],&2);&&&&&&&&&&end&&&&&&&&&&else&&&&&&&&&&WriteLn(&'CryptGetHashParam&ERROR&--&&'&+&SysErrorMessage(GetLastError))&;&&&&&&&&&&end&&&&&&&&&&else&&&&&&&&&&WriteLn(&'CryptHashData&ERROR&--&&'&+&SysErrorMessage(GetLastError))&;&&&&&&&&&&{destroy&hash-object}&&&&&&&&&&CryptDestroyHash(hHmacHash);&&&&&&&&&&CryptDestroyKey(hKey);&&&&&&&&&&end&&&&&&&&&&else&&&&&&&&&&WriteLn(&'CryptSetHashParam&ERROR&--&&'&+&SysErrorMessage(GetLastError))&;&&&&&&&&&&end&&&&&&&&&&else&&&&&&&&&&WriteLn(&'CryptCreateHash&ERROR&--&&'&+&SysErrorMessage(GetLastError))&;&&&&&&&&end&&&&&&&&else&&&&&&&&&&WriteLn(&'CryptDeriveKey&ERROR&--&&'&+&SysErrorMessage(GetLastError))&;&&&&&&&&&&&&{destroy&hash-object}&&&&&&CryptDestroyHash(hHash);&&&&&&&&{release&the&context&for&crypt&default&provider}&&&&CryptReleaseContext(hCryptProvider,&0);&&&&Result&:=&AnsiLowerCase(Result);
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
我个人建议你直接调用系统的API进行签名.
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
刚才看了下支付宝的开发文档签名算法是HMAC的,建议你直接调用系统API或者Openssl的HMAC接口.
----------------------------------------------
ly123 (ly123)
▲▲▲▲▲
盒子活跃会员
<font color="#楼:
衷心感谢&xuchuantao&的热心帮助,我会根据您的建议去试一下,还有一种方法就是利用支付宝的Demo中的方法用C#写了一个计算签名的dll,调用这个dll也能计算签名&&ole_rsa&:=&CreateOleObject('ClassLibrary2.TestClass');&&rsa_sign&:=&ole_rsa.RSASignCharSet(liststr_str,'rsa_private_key.pem','utf-8');但是这种方法需要在客户的机器上注册这个dll,并且还要求装有高版本的Framework
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
如果要用快捷支付.可以使用tplockbox或者RAPWare&EasyCrypt这两个控件组.这两个都是可以进行RSA的签名操作的.系统CryptSignHash这个API也可以进行签名操作.
----------------------------------------------
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
刚才看了下fundamentalslib的代码也是可以进行RSA的签名的,不过推荐使用RAPWare&EasyCrypt他是对系统CryptoAPI加密接口的封装,RSA签名微软是已经实现了的.例子在控件里有.
----------------------------------------------
138soft (138soft)
▲▲▲▲▲
盒子活跃会员
<font color="#楼:
上次也有个朋友来问这个问题。后来我用SecureBlackbox花了3分钟帮他解决了。免DLL。
----------------------------------------------
是你上错了车,还是我下错了站?
138soft (138soft)
▲▲▲▲▲
盒子活跃会员
<font color="#楼:
其实RSA加密是有一定标准的。例如C#之类的,加密后的内容肯定等于密钥位数除以8。不知道是否是明文规定。JAVA之类的,对数字证书则有一定要求,私钥的证书,ASN.1编码的时候前面需要再加两个Item---虽然没什么用,但你不加它就读取失败。
----------------------------------------------
是你上错了车,还是我下错了站?
xuchuantao (暗黑天使)
▲▲▲△△
<font color="#楼:
能共享一下SecureBlackbox吗谢谢.
----------------------------------------------
rmmis (rmmis)
▲▲▲△△
<font color="#楼:
----------------------------------------------
eastroads (eastroads)
▲▲▲▲▲
<font color="#楼:
很多热心的朋友,赞你们!
----------------------------------------------
blbz (冰力不足)
▲▲▲▲△
<font color="#楼:
----------------------------------------------
rmmis (rmmis)
▲▲▲△△
<font color="#楼:
----------------------------------------------
adden_lian (寻秦冷雨夜)
▲▲▲▲▲
盒子活跃会员
<font color="#楼:
上面一些知道的人不说,弄了几天总算好了,现贴上代码:function&Sign(filename,msg&:&String):&&&&&&var&&&&&&&&&&&ctx&:&EVP_MD_CTX&&&;&&&&&&&&&&&buf_in:P&&&&&&&&&&&m_len&:&C&&&&&&&&&outl&:&C&&&&&&&&&pKey&:&PEVP_PKEY;&&&&&&&&&m,buf_out:array&&&[0..1024]&&&of&&&&&&&&&&&&i:I&&&&&&&&&s:&TStringS&&&&&&&&&d:&TStringS&&&&&&&&&iKeyLen:&I&&&&&&&begin&&&&&&&//buf_out:='';&&&&&if&filename=''&then&&&&&&&begin&&&&&&&Result:='';&&&&&&&&&E&&&&&&&&&&&&&&&&pKey&:=&LoadPrivateKey(filename);&&&&&&&buf_in&:=&PChar(msg);&&&&&&&EVP_MD_CTX_init(@ctx);&&&&&&&&&&//初始化&&&&&&&EVP_SignInit(@ctx,EVP_sha1());&&&&//将需要使用的摘要算法存入ctxl中&&&&&&&EVP_SignUpdate(@ctx,buf_in,Length(buf_in));//存入编码值&&&&&&&EVP_DigestFinal(@ctx,m,m_len);&&&&//求取编码的长度为m_len摘要值存入m中&&&&&&&rSA_sign(EVP_sha1()._type,m,m_len,buf_out,@outl,pkey.pkey.rsa);&//64为SHA1的NID&&&&&&&EVP_MD_CTX_cleanup(@ctx);&&&&&&&s&:=&TStringStream.Create('');&&&&&&&d&:=&TStringStream.Create('');&&&&&&&iKeyLen&:=&PCardinal(@outl)^;&&&&&&&try&&&&&&&&&s.WriteBuffer(buf_out,&iKeyLen);&&&&&&&&&s.Position&:=&0;&&&&&&&&&EncodeStream(s,&d);&&&&&&&&&Result&:=&d.DataS&&&&&&&finally&&&&&&&&&s.F&&&&&&&&&d.F&&&&&&&&&&&
----------------------------------------------
olddelphier (oldDelphier)
▲▲△△△
<font color="#楼:
多谢老兄用你的这个代码感觉成功率很高,试了10来次都没有出现那个签名错误的提示了用以前网上下载的基本上3成会签名错误,要循环使用才能达到9成5以上成功率
----------------------------------------------
发表评论:
馆藏&21734
TA的最新馆藏[转]&主题 : 请教大神,支付宝签名问题!!!!
级别: 新手上路
可可豆: 97 CB
威望: 97 点
在线时间: 102(时)
发自: Web Page
来源于&&分类
请教大神,支付宝签名问题!!!!&&&
在做支付宝支付功能时,因为需要加密的签名来调起支付,后台在签名这一块儿遇到问题,做不了签名,而ios使用支付宝的官方Demo(签名在前端完成),可以很顺利的运行,目前老板着急APP上架,我想问下各位大神,你们有没有把签名放在前端去做的?尽管支付宝再三提示说签名一定要放在后台,不然会产生安全问题,如果我们后台做不了签名,只能放在前端的话,会不会苹果不让上架?以后会不会很容易泄露用户信息?
级别: 侠客
UID: 599895
可可豆: 260 CB
威望: 252 点
在线时间: 165(时)
发自: Web Page
应该会让上架的,前段搞签名很不安全,很不安全,很不安全
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版

我要回帖

更多关于 请教大神这是什么歌 的文章

 

随机推荐