首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > asp.net >

没有搞过,求实现

2012-06-22 
没搞过,求实现,旧版鉴权参数的sign算法跟原来一样保持不变,旧版的鉴权参数在API接口调用时需要传的鉴权参

没搞过,求实现,
旧版鉴权参数的sign算法跟原来一样保持不变,
旧版的鉴权参数在API接口调用时需要传的鉴权参数名称有:spid,token,uin、sign
/
只有在fuwu平台申请到的新版的鉴权,才需要采用新版的sign算法
新版的鉴权参数在API接口调用时需要传的鉴权参数名称有:appOAuthID,accessToken,uin、sign
/

新版鉴权系统也需要提供多两个参数:
timeStamp:当前的系统时间戳,单位为秒
randomValue:随机值的整数(100009999999999)

/


拍拍开放平台第三方应用签名参数sign的说明


本文档仅适用于OpenAPI 新版鉴权参数的签名生成,由于是通用说明,本文中仅以/deal/sellerSearchDealList.xhtml的签名生成作为示例。

签名值sign是将请求源串以及密钥根据一定签名方法生成的签名值,用来提高传输过程参数的防篡改性。
签名值的生成共有3个步骤:构造源串,构造密钥,生成签名值。详见下面的描述。

Step 1. 构造源串

源串是由3部分内容用“&”拼接起来的: HTTP请求方式 & urlencode(uri) & urlencode(a=x&b=y&...)
源串构造步骤如下:
第1步:将请求的URI路径进行URL编码(URI不含host,URI示例:/deal/sellerSearchDealList.xhtml)
请开发者关注:URL编码注意事项,否则容易导致后面签名不能通过验证。

第2步:将除“sign”外的所有参数按key进行字典升序排列。 
注:除非OpenAPI文档中特别标注了某参数不参与签名,否则除sign外的所有参数都要参与签名。

第3步:将第2步中排序后的参数(key=value)用&拼接起来,并进行URL编码。
请开发者关注:URL编码注意事项,否则容易导致后面签名不能通过验证。 

第4步:将HTTP请求方式(GET或者POST)以及第1步和第3步中的字符串用&拼接起来。 

源串构造示例如下
(由于是通用说明,这里以/deal/sellerSearchDealList.xhtml作为示例,且示例中的请求串不可直接复制访问)
1. 原始请求信息:
HTTP请求方式:GET
请求的URI路径(不含HOST):/deal/sellerSearchDealList.xhtml
secretOAuthKey:xxxFFOr1vD5lL9D0
请求参数:accessToken=2b739b7fed2c4a4a7a3a20b646ee3e87&appOAuthID=700000056&timeStamp=1336719949712&uin=214689727&randomValue=123321

2. 下面开始构造源串: 
第1步:将请求的URI路径进行URL编码,得到: %2Fdeal%2FsellerSearchDealList.xhtml 

第2步:将除“sign”外的所有参数按key进行字典升序排列,排列结果为:accessToken,appOAuthID,randomValue,timeStamp,uin 


第3步:将第2步中排序后的参数(key=value)用&拼接起来:
accessToken=2b739b7fed2c4a4a7a3a20b646ee3e87&appOAuthID=700000056&randomValue=123321&timeStamp=1336732259249&uin=214689727
 
然后进行URL编码( 编码时请关注URL编码注意事项,否则容易导致后面签名不能通过验证),编码结果为:
accessToken%3D2b739b7fed2c4a4a7a3a20b646ee3e87%26appOAuthID%3D700000056%26randomValue
%3D123321%26timeStamp%3D1336732259249%26uin%3D214689727

第4步:将HTTP请求方式,第1步以及第3步中的到的字符串用&拼接起来,得到源串:
GET&%2Fdeal%2FsellerSearchDealList.xhtml&accessToken%3D2b739b7fed2c4a4a7a3a20b646ee3e87
%26appOAuthID%3D700000056%26randomValue%3D123321%26timeStamp%3D1336732259249%26uin%3D214689727

Step 2. 构造密钥

得到密钥的方式:在应用的secretOAuthKey末尾加上一个字节的“&”,即secretOAuthKey&,例如:
xxxFFOr1vD5lL9D0&
Step 3. 生成签名值

1. 使用HMAC-SHA1加密算法,将Step1中的到的源串以及Step2中得到的密钥进行加密。 
(注:一般程序语言中会内置HMAC-SHA1加密算法的函数,例如PHP5.1.2之后的版本可直接调用hash_hmac函数。)

2. 然后将加密后的字符串经过Base64编码。 
(注:一般程序语言中会内置Base64编码函数,例如PHP中可直接调用 base64_encode() 函数。)

3. 得到的签名值结果如下:
zRXOeH3tIdKAf9fUWUwcvoAjyjs=


常见错误排障

签名校验失败分为以下两种情况:
1. sign参数生成错误
有可能由下列原因引起:
(1)构造源串时注意URI不含host,如/deal/sellerSearchDealList.xhtml,而不是http://api.paipai.com/deal/sellerSearchDealList.xhtml
(2)构造源串时,没有将key排序后,再将(key=value)用&拼接起来。
(3)构造密钥时,没有将secretOAuthKey后加“&”。
(4)某些语言的URLEncode系统方法在进行URL编码时,并没有按照现行的URL编码规则进行。详见下文的:URL编码注意事项。 
 

2. sign参数生成正确,但是参数传输前没有进行URL编码。
所有参数传输时都要进行URL编码,包括sign。如果没有进行URL编码,则即使sig是正确的,但是校验sig时不能匹配。

URL编码注意事项
URL编码规则:
签名验证时,要求对字符串中除了“-”、“_”、“.”之外的所有非字母数字字符都替换成百分号(%)后跟两位十六进制数。
十六进制数中字母必须为大写。

注意事项:
1. 某些系统方法,例如.NET系统方法HttpUtility.UrlEncode会将‘=’编码成‘%3d’,而不是%3D,导致加密签名通不过验证,请开发者注意检查。

2.Java 1.3和早期版本中,调用类java.net.URLEncoder下的方法进行URL编码时,某些特殊字符并不会被编码。特殊字符包括: (.)、(-)、(*) 和 (_) 。
因此如果字符串中含星号(*)会导致生成的签名不能通过验证。

3. 某些语言的urlencode方法会把“空格”编码为“+”,实际上应该编码为“%20”。这也将生成错误的签名,导致签名通不过验证。 
请开发者注意检查,手动将“+”替换为“%20”。
在PHP中,推荐用rawurlencode方法进行URL编码。




[解决办法]
LZ要的是加密?还有没有看出来为啥会得出zRXOeH3tIdKAf9fUWUwcvoAjyjs=这个结果呢
[解决办法]
很明显 你“解密”不对啊。


你跟踪下这个(单步调试) 看需求在那个地方加字符
HMACSHA1 myHMACSHA1 = new HMACSHA1(Encoding.Default.GetBytes(encryptKey));
byte[] RstRes = myHMACSHA1.ComputeHash(Encoding.Default.GetBytes(encryptText));

StringBuilder EnText = new StringBuilder();
[解决办法]
using System; 
using System.Collections; 
using System.IO; 
using System.Text;

namespace VerifySHA1
{
public class MySHA1

// state variables 
private static UInt32 Message_Digest1 = 0x67452301;
private static UInt32 Message_Digest2 = 0xEFCDAB89;
private static UInt32 Message_Digest3 = 0x98BADCFE;
private static UInt32 Message_Digest4 = 0x10325476;
private static UInt32 Message_Digest5 = 0xC3D2E1F0;

private static UInt32 SHA1CircularShift(int bits,UInt32 word) 
{
return ((word << bits) & 0xFFFFFFFF) | (word) >> (32-(bits));
}

private static void SHA1_Init()

Message_Digest1 = 0x67452301;
Message_Digest2 = 0xEFCDAB89;
Message_Digest3 = 0x98BADCFE;
Message_Digest4 = 0x10325476;
Message_Digest5 = 0xC3D2E1F0;


private static UInt32[] SHA1_Append(byte[] input)

int zeros=0; 
int ones =1; 
int size=0; 
int n = input.Length; 
int m = n%64; 
if( m < 56 )

zeros = 55-m; 
size=n-m+64; 

else if (m==56)

zeros = 63; 
ones = 1; 
size=n+8+64; 

else

zeros = 63-m+56; 
size=n+64-m+64; 


ArrayList bs = new ArrayList(input); 
if(ones==1)

bs.Add( (byte)0x80 ); // 0x80 = 10000000 

for(int i=0;i<zeros;i++)

bs.Add( (byte)0 ); 


UInt64 N = (UInt64) n * 8; 
byte h8=(byte)(N&0xFF); 
byte h7=(byte)((N>>8)&0xFF); 
byte h6=(byte)((N>>16)&0xFF); 
byte h5=(byte)((N>>24)&0xFF); 
byte h4=(byte)((N>>32)&0xFF); 
byte h3=(byte)((N>>40)&0xFF); 
byte h2=(byte)((N>>48)&0xFF); 
byte h1=(byte)(N>>56); 
bs.Add(h1); 
bs.Add(h2); 
bs.Add(h3); 
bs.Add(h4); 
bs.Add(h5); 
bs.Add(h6); 
bs.Add(h7); 
bs.Add(h8); 
byte[] ts=(byte[])bs.ToArray(typeof(byte)); 

/* Decodes input (byte[]) into output (UInt32[]). Assumes len is 
* a multiple of 4. 
*/ 
UInt32[] output = new UInt32[size/4]; 
for(Int64 i=0,j=0;i<size;j++,i+=4)
{
UInt32 temp = 0;
temp=temp|(((UInt32)ts[i])<<24);
temp=temp|(((UInt32)ts[i+1])<<16);
temp=temp|(((UInt32)ts[i+2])<<8);
temp=temp|(((UInt32)ts[i+3]));


output[j] = temp;

return output; 

private static UInt32[] SHA1_Transform(UInt32[] x)

SHA1_Init();

UInt32[] K = {
0x5A827999,
0x6ED9EBA1,
0x8F1BBCDC,
0xCA62C1D6
};
int t;
UInt32 temp;
UInt32[] W = new UInt32[80];
UInt32 A, B, C, D, E;

for(int k=0; k<x.Length; k+=16)
{
for(t = 0; t < 16; t++)
{
W[t] = x[t+k];
}

for(t = 16; t < 80; t++)
{
W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
}

A = Message_Digest1;
B = Message_Digest2;
C = Message_Digest3;
D = Message_Digest4;
E = Message_Digest5;

for(t = 0; t < 20; t++)
{
temp = SHA1CircularShift(5,A) +
((B & C) | ((~B) & D)) + E + W[t] + K[0];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}

for(t = 20; t < 40; t++)
{
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}

for(t = 40; t < 60; t++)
{
temp = SHA1CircularShift(5,A) +
((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}

for(t = 60; t < 80; t++)
{
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}

Message_Digest1 = (Message_Digest1 + A) & 0xFFFFFFFF;
Message_Digest2 = (Message_Digest2 + B) & 0xFFFFFFFF;
Message_Digest3 = (Message_Digest3 + C) & 0xFFFFFFFF;
Message_Digest4 = (Message_Digest4 + D) & 0xFFFFFFFF;
Message_Digest5 = (Message_Digest5 + E) & 0xFFFFFFFF;
}

return new UInt32[]{Message_Digest1,Message_Digest2,Message_Digest3,Message_Digest4,Message_Digest5}; 

public static string SHA1Array(UInt32[] input)

StringBuilder sb = new StringBuilder();

for(int i=0; i<input.Length; i++)
{
sb.Append( String.Format("{0:X8}", input[i]).ToUpper() );
}

return sb.ToString(); 


public static string MySHA1String(string message)

char[] c = message.ToCharArray(); 


byte[] b = new byte[c.Length]; 
for(int i=0;i<c.Length;i++)

b[i]=(byte)c[i]; 

UInt32[] output = SHA1_Append( b );
UInt32[] str = SHA1_Transform( output );
return SHA1Array(str);


public static string MySHA1File(string fileName)

FileStream fs=File.Open(fileName,FileMode.Open,FileAccess.Read); 
byte[] array=new byte[fs.Length]; 
fs.Read(array,0,(int)fs.Length); 
fs.Close(); 
UInt32[] output = SHA1_Append( array );
UInt32[] str = SHA1_Transform( output );
return SHA1Array(str);

#region Unit Test
public static string Test(string message)

return "\r\nSHA1 (\""+message+"\") = " + MySHA1String(message); 

public static string TestSuite()
{
string s = ""; 
s+=Test(""); 
s+=Test("a"); 
s+=Test("abc"); 
s+=Test("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); 
s+=Test("abcdefghijklmnopqrstuvwxyz"); 
s+=Test("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 
s+=Test("12345678901234567890123456789012345678901234567890123456789012345678901234567890"); 
// StringBuilder sb = new StringBuilder();
// for(int i=0; i<1000000; i++)
// sb.Append("a");
// s+=Test(sb.ToString());

return s;


public static void Main()
{
Console.WriteLine(MySHA1.TestSuite());
Console.ReadLine();
}
#endregion

}

[解决办法]
楼主问题有没有解决了,求教~~~~
[解决办法]
private string GetSHA1(string signatureBase,string appKey)
{
System.Security.Cryptography.HMACSHA1 hmacsha1 = new System.Security.Cryptography.HMACSHA1();
hmacsha1.Key = System.Text.Encoding.ASCII.GetBytes(string.Format("{0}&", HttpUtility.UrlEncode(appKey)));

byte[] dataBuffer = System.Text.Encoding.ASCII.GetBytes(signatureBase); //signatureBase要进行签名的基础字符串
byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);

return Convert.ToBase64String(hashBytes);
}

我算的结果到没错 但提交回去已然返回 -5
[解决办法]
private string GetSHA1(string signatureBase,string appKey)
{
System.Security.Cryptography.HMACSHA1 hmacsha1 = new System.Security.Cryptography.HMACSHA1();
hmacsha1.Key = System.Text.Encoding.ASCII.GetBytes(string.Format("{0}&", HttpUtility.UrlEncode(appKey)));

byte[] dataBuffer = System.Text.Encoding.ASCII.GetBytes(signatureBase); //signatureBase要进行签名的基础字符串
byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);

return Convert.ToBase64String(hashBytes);
}


结果计算没问题 但是依然返回-5 我也很无奈。。。

热点排行