微信公共平台验证接口JAVA实现
海南中立科技 | 2018-01-26 23:53:52 | 阅读:41400
看到微信的公共平台接入文档接口验证的例子是PHP写的,对于很多不是做php的人来说有点麻烦,虽然编程思想是相同的,逻辑也很简单,但是一种语言有一种语言的语法规范,其实代码的编写还是差距挺大的。这里写一下JAVA版接口验证的实现。response.setContentType("text/html");PrintWriterout=response.getWriter();Stringsignature=request.getParameter("signature");Stringtimestamp=request.getParameter("timestamp");Stringnonce=request.getParameter("nonce");Stringechostr=request.getParameter("echostr");StringreSignature=null;try{String[]str={TOKEN,timestamp,nonce};Arrays.sort(str);StringbigStr=str[0]+str[1]+str[2];reSignature=newSHA1().getDigestOfString(bigStr.getBytes()).toLowerCase();}catch(Exceptione){e.printStackTrace();}if(null!=reSignature&&reSignature.equals(signature)){//请求来自微信out.print(echostr);}else{out.print("errorrequest!therequestisnotfromweixinserver");}out.flush();out.close();复制代码逻辑代码就这些,就是按照文档上说的来:1.将token、timestamp、nonce三个参数进行字典序排序2.将三个参数字符串拼接成一个字符串进行sha1加密3.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信上面代码中有一个工具类SHA1,就是实现了一个加密解密算法,网上也有,这里贴一下代码。packageduanqing.test.servlet.tools;publicclassSHA1{privatefinalint[]abcde={0x67452301,0xefcdab89,0x98badcfe,0x10325476,0xc3d2e1f0};//摘要数据存储数组privateint[]digestInt=newint[5];//计算过程中的临时数据存储数组privateint[]tmpData=newint[80];//计算sha-1摘要privateintprocess_input_bytes(byte[]bytedata){//初试化常量System.arraycopy(abcde,0,digestInt,0,abcde.length);//格式化输入字节数组,补10及长度数据byte[]newbyte=byteArrayFormatData(bytedata);//获取数据摘要计算的数据单元个数intMCount=newbyte.length/64;//循环对每个数据单元进行摘要计算for(intpos=0;pos<MCount;pos++){//将每个单元的数据转换成16个整型数据,并保存到tmpData的前16个数组元素中for(intj=0;j<16;j++){tmpData[j]=byteArrayToInt(newbyte,(pos*64)+(j*4));}//摘要计算函数encrypt();}return20;}//格式化输入字节数组格式privatebyte[]byteArrayFormatData(byte[]bytedata){//补0数量intzeros=0;//补位后总位数intsize=0;//原始数据长度intn=bytedata.length;//模64后的剩余位数intm=n%64;//计算添加0的个数以及添加10后的总长度if(m<56){zeros=55-m;size=n-m+64;}elseif(m==56){zeros=63;size=n+8+64;}else{zeros=63-m+56;size=(n+64)-m+64;}//补位后生成的新数组内容byte[]newbyte=newbyte[size];//复制数组的前面部分System.arraycopy(bytedata,0,newbyte,0,n);//获得数组Append数据元素的位置intl=n;//补1操作newbyte[l++]=(byte)0x80;//补0操作for(inti=0;i<zeros;i++){newbyte[l++]=(byte)0x00;}//计算数据长度,补数据长度位共8字节,长整型longN=(long)n*8;byteh8=(byte)(N&0xFF);byteh7=(byte)((N>>8)&0xFF);byteh6=(byte)((N>>16)&0xFF);byteh5=(byte)((N>>24)&0xFF);byteh4=(byte)((N>>32)&0xFF);byteh3=(byte)((N>>40)&0xFF);byteh2=(byte)((N>>48)&0xFF);byteh1=(byte)(N>>56);newbyte[l++]=h1;newbyte[l++]=h2;newbyte[l++]=h3;newbyte[l++]=h4;newbyte[l++]=h5;newbyte[l++]=h6;newbyte[l++]=h7;newbyte[l++]=h8;returnnewbyte;}privateintf1(intx,inty,intz){return(x&y)|(~x&z);}privateintf2(intx,inty,intz){returnx^y^z;}privateintf3(intx,inty,intz){return(x&y)|(x&z)|(y&z);}privateintf4(intx,inty){return(x<<y)|x>>>(32-y);}//单元摘要计算函数privatevoidencrypt(){for(inti=16;i<=79;i++){tmpData[i]=f4(tmpData[i-3]^tmpData[i-8]^tmpData[i-14]^tmpData[i-16],1);}int[]tmpabcde=newint[5];for(inti1=0;i1<tmpabcde.length;i1++){tmpabcde[i1]=digestInt[i1];}for(intj=0;j<=19;j++){inttmp=f4(tmpabcde[0],5)+f1(tmpabcde[1],tmpabcde[2],tmpabcde[3])+tmpabcde[4]+tmpData[j]+0x5a827999;tmpabcde[4]=tmpabcde[3];tmpabcde[3]=tmpabcde[2];tmpabcde[2]=f4(tmpabcde[1],30);tmpabcde[1]=tmpabcde[0];tmpabcde[0]=tmp;}for(intk=20;k<=39;k++){inttmp=f4(tmpabcde[0],5)+f2(tmpabcde[1],tmpabcde[2],tmpabcde[3])+tmpabcde[4]+tmpData[k]+0x6ed9eba1;tmpabcde[4]=tmpabcde[3];tmpabcde[3]=tmpabcde[2];tmpabcde[2]=f4(tmpabcde[1],30);tmpabcde[1]=tmpabcde[0];tmpabcde[0]=tmp;}for(intl=40;l<=59;l++){inttmp=f4(tmpabcde[0],5)+f3(tmpabcde[1],tmpabcde[2],tmpabcde[3])+tmpabcde[4]+tmpData[l]+0x8f1bbcdc;tmpabcde[4]=tmpabcde[3];tmpabcde[3]=tmpabcde[2];tmpabcde[2]=f4(tmpabcde[1],30);tmpabcde[1]=tmpabcde[0];tmpabcde[0]=tmp;}for(intm=60;m<=79;m++){inttmp=f4(tmpabcde[0],5)+f2(tmpabcde[1],tmpabcde[2],tmpabcde[3])+tmpabcde[4]+tmpData[m]+0xca62c1d6;tmpabcde[4]=tmpabcde[3];tmpabcde[3]=tmpabcde[2];tmpabcde[2]=f4(tmpabcde[1],30);tmpabcde[1]=tmpabcde[0];tmpabcde[0]=tmp;}for(inti2=0;i2<tmpabcde.length;i2++){digestInt[i2]=digestInt[i2]+tmpabcde[i2];}for(intn=0;n<tmpData.length;n++){tmpData[n]=0;}}//4字节数组转换为整数privateintbyteArrayToInt(byte[]bytedata,inti){return((bytedata[i]&0xff)<<24)|((bytedata[i+1]&0xff)<<16)|((bytedata[i+2]&0xff)<<8)|(bytedata[i+3]&0xff);}//整数转换为4字节数组privatevoidintToByteArray(intintValue,byte[]byteData,inti){byteData[i]=(byte)(intValue>>>24);byteData[i+1]=(byte)(intValue>>>16);byteData[i+2]=(byte)(intValue>>>8);byteData[i+3]=(byte)intValue;}//将字节转换为十六进制字符串privatestaticStringbyteToHexString(byteib){char[]Digit={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};char[]ob=newchar[2];ob[0]=Digit[(ib>>>4)&0X0F];ob[1]=Digit[ib&0X0F];Strings=newString(ob);returns;}//将字节数组转换为十六进制字符串privatestaticStringbyteArrayToHexString(byte[]bytearray){StringstrDigest="";for(inti=0;i<bytearray.length;i++){strDigest+=byteToHexString(bytearray[i]);}returnstrDigest;}//计算sha-1摘要,返回相应的字节数组publicbyte[]getDigestOfBytes(byte[]byteData){process_input_bytes(byteData);byte[]digest=newbyte[20];for(inti=0;i<digestInt.length;i++){intToByteArray(digestInt[i],digest,i*4);}returndigest;}//计算sha-1摘要,返回相应的十六进制字符串publicStringgetDigestOfString(byte[]byteData){returnbyteArrayToHexString(getDigestOfBytes(byteData));}publicstaticvoidmain(String[]args){Stringdata="123456";System.out.println(data);Stringdigest=newSHA1().getDigestOfString(data.getBytes()).toLowerCase();System.out.println(digest);//System.out.println(ToMD5.convertSHA1(data).toUpperCase());}}复制代码