审计记录

src/org/theyeasy/weixin/util/SHA1.java 10.8 KB
zxt@theyeasy.com committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
/**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 * 
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */

// ------------------------------------------------------------------------

package org.theyeasy.weixin.util;

import java.security.MessageDigest;
import java.util.Arrays;

/**
 * SHA1 class
 *
 * 计算公众平台的消息签名接口.
 */
class SHA1 {
	 
	/**
	 * 用SHA1算法生成安全签名
	 * 
	 * @param token
	 *            票据
	 * @param timestamp
	 *            时间戳
	 * @param nonce
	 *            随机字符串
	 * @param encrypt
	 *            密文
	 * @return 安全签名
	 * @throws AesException
	 */
	public static String getSHA1(String token, String timestamp, String nonce, String encrypt) throws AesException {
		try {
			String[] array = new String[] { token, timestamp, nonce, encrypt };
			StringBuffer sb = new StringBuffer();
			// 字符串排序
			Arrays.sort(array);
			for (int i = 0; i < 4; i++) {
				sb.append(array[i]);
			}
			String str = sb.toString();
			// SHA1签名生成
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			md.update(str.getBytes());
			byte[] digest = md.digest();

			StringBuffer hexstr = new StringBuffer();
			String shaHex = "";
			for (int i = 0; i < digest.length; i++) {
				shaHex = Integer.toHexString(digest[i] & 0xFF);
				if (shaHex.length() < 2) {
					hexstr.append(0);
				}
				hexstr.append(shaHex);
			}
			return hexstr.toString();
		} catch (Exception e) {
			e.printStackTrace();
			throw new AesException(AesException.ComputeSignatureError);
		}
	}
 
	 public static String getSHA1HexString(String str) throws Exception {  
	        // SHA1签名生成  
	        MessageDigest md = MessageDigest.getInstance("SHA-1");  
	        md.update(str.getBytes());  
	        byte[] digest = md.digest();  
	  
	        StringBuffer hexstr = new StringBuffer();  
	        String shaHex = "";  
	        for (int i = 0; i < digest.length; i++) {  
	            shaHex = Integer.toHexString(digest[i] & 0xFF);  
	            if (shaHex.length() < 2) {  
	                hexstr.append(0);  
	            }  
	            hexstr.append(shaHex);  
	        }  
	        return hexstr.toString();  
	    }  
	      
	      
	    private final int[] abcde = {     
	            0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0     
	        };     
	    // 摘要数据存储数组     
	    private int[] digestInt = new int[5];     
	    // 计算过程中的临时数据存储数组     
	    private int[] tmpData = new int[80];     
	    // 计算sha-1摘要     
	    private int process_input_bytes(byte[] bytedata) {     
	        // 初试化常量     
	        System.arraycopy(abcde, 0, digestInt, 0, abcde.length);     
	        // 格式化输入字节数组,补10及长度数据     
	        byte[] newbyte = byteArrayFormatData(bytedata);     
	        // 获取数据摘要计算的数据单元个数     
	        int MCount = newbyte.length / 64;     
	        // 循环对每个数据单元进行摘要计算     
	        for (int pos = 0; pos < MCount; pos++) {     
	            // 将每个单元的数据转换成16个整型数据,并保存到tmpData的前16个数组元素中     
	            for (int j = 0; j < 16; j++) {     
	                tmpData[j] = byteArrayToInt(newbyte, (pos * 64) + (j * 4));     
	            }     
	            // 摘要计算函数     
	            encrypt();     
	        }     
	        return 20;     
	    }     
	    // 格式化输入字节数组格式     
	    private byte[] byteArrayFormatData(byte[] bytedata) {     
	        // 补0数量     
	        int zeros = 0;     
	        // 补位后总位数     
	        int size = 0;     
	        // 原始数据长度     
	        int n = bytedata.length;     
	        // 模64后的剩余位数     
	        int m = n % 64;     
	        // 计算添加0的个数以及添加10后的总长度     
	        if (m < 56) {     
	            zeros = 55 - m;     
	            size = n - m + 64;     
	        } else if (m == 56) {     
	            zeros = 63;     
	            size = n + 8 + 64;     
	        } else {     
	            zeros = 63 - m + 56;     
	            size = (n + 64) - m + 64;     
	        }     
	        // 补位后生成的新数组内容     
	        byte[] newbyte = new byte[size];     
	        // 复制数组的前面部分     
	        System.arraycopy(bytedata, 0, newbyte, 0, n);     
	        // 获得数组Append数据元素的位置     
	        int l = n;     
	        // 补1操作     
	        newbyte[l++] = (byte) 0x80;     
	        // 补0操作     
	        for (int i = 0; i < zeros; i++) {     
	            newbyte[l++] = (byte) 0x00;     
	        }     
	        // 计算数据长度,补数据长度位共8字节,长整型     
	        long N = (long) 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);     
	        newbyte[l++] = h1;     
	        newbyte[l++] = h2;     
	        newbyte[l++] = h3;     
	        newbyte[l++] = h4;     
	        newbyte[l++] = h5;     
	        newbyte[l++] = h6;     
	        newbyte[l++] = h7;     
	        newbyte[l++] = h8;     
	        return newbyte;     
	    }     
	    private int f1(int x, int y, int z) {     
	        return (x & y) | (~x & z);     
	    }     
	    private int f2(int x, int y, int z) {     
	        return x ^ y ^ z;     
	    }     
	    private int f3(int x, int y, int z) {     
	        return (x & y) | (x & z) | (y & z);     
	    }     
	    private int f4(int x, int y) {     
	        return (x << y) | x >>> (32 - y);     
	    }     
	    // 单元摘要计算函数     
	    private void encrypt() {     
	        for (int i = 16; i <= 79; i++) {     
	            tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14] ^     
	                    tmpData[i - 16], 1);     
	        }     
	        int[] tmpabcde = new int[5];     
	        for (int i1 = 0; i1 < tmpabcde.length; i1++) {     
	            tmpabcde[i1] = digestInt[i1];     
	        }     
	        for (int j = 0; j <= 19; j++) {     
	            int tmp = 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 (int k = 20; k <= 39; k++) {     
	            int tmp = 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 (int l = 40; l <= 59; l++) {     
	            int tmp = 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 (int m = 60; m <= 79; m++) {     
	            int tmp = 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 (int i2 = 0; i2 < tmpabcde.length; i2++) {     
	            digestInt[i2] = digestInt[i2] + tmpabcde[i2];     
	        }     
	        for (int n = 0; n < tmpData.length; n++) {     
	            tmpData[n] = 0;     
	        }     
	    }     
	    // 4字节数组转换为整数     
	    private int byteArrayToInt(byte[] bytedata, int i) {     
	        return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16) |     
	        ((bytedata[i + 2] & 0xff) << 8) | (bytedata[i + 3] & 0xff);     
	    }     
	    // 整数转换为4字节数组     
	    private void intToByteArray(int intValue, byte[] byteData, int i) {     
	        byteData[i] = (byte) (intValue >>> 24);     
	        byteData[i + 1] = (byte) (intValue >>> 16);     
	        byteData[i + 2] = (byte) (intValue >>> 8);     
	        byteData[i + 3] = (byte) intValue;     
	    }     
	    // 将字节转换为十六进制字符串     
	    private static String byteToHexString(byte ib) {     
	        char[] Digit = {     
	                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',     
	                'D', 'E', 'F'     
	            };     
	        char[] ob = new char[2];     
	        ob[0] = Digit[(ib >>> 4) & 0X0F];     
	        ob[1] = Digit[ib & 0X0F];     
	        String s = new String(ob);     
	        return s;     
	    }     
	    // 将字节数组转换为十六进制字符串     
	    private static String byteArrayToHexString(byte[] bytearray) {     
	        String strDigest = "";     
	        for (int i = 0; i < bytearray.length; i++) {     
	            strDigest += byteToHexString(bytearray[i]);     
	        }     
	        return strDigest;     
	    }     
	    // 计算sha-1摘要,返回相应的字节数组     
	    public byte[] getDigestOfBytes(byte[] byteData) {     
	        process_input_bytes(byteData);     
	        byte[] digest = new byte[20];     
	        for (int i = 0; i < digestInt.length; i++) {     
	            intToByteArray(digestInt[i], digest, i * 4);     
	        }     
	        return digest;     
	    }     
	    // 计算sha-1摘要,返回相应的十六进制字符串     
	    public String getDigestOfString(byte[] byteData) {     
	        return byteArrayToHexString(getDigestOfBytes(byteData));     
	    }     
	      
	      
	    /**/  
	    public static void main(String[] args) {     
	        String data = "lvbaolin";     
	        System.out.println(data);     
	        String digest = new SHA1().getDigestOfString(data.getBytes());     
	        System.out.println(digest);    
	           
	       // System.out.println( ToMD5.convertSHA1(data).toUpperCase());    
	    }   
	
}