RSA/RSA2 进行签名和验签

  1 package com.byttersoft.hibernate.erp.szmy.util;
  2 
  3 import java.io.ByteArrayInputStream;
  4 import java.io.IOException;
  5 import java.io.InputStream;
  6 import java.io.InputStreamReader;
  7 import java.io.Reader;
  8 import java.io.StringWriter;
  9 import java.io.Writer;
 10 import java.security.KeyFactory;
 11 import java.security.PrivateKey;
 12 import java.security.PublicKey;
 13 import java.security.spec.PKCS8EncodedKeySpec;
 14 import java.security.spec.X509EncodedKeySpec;
 15 import java.util.ArrayList;
 16 import java.util.Collections;
 17 import java.util.List;
 18 import java.util.Map;
 19 
 20 import org.apache.commons.codec.binary.Base64;
 21 
 22 import com.byttersoft.framework.util.StringUtil;
 23 /**
 24  * RSA的签名及验签
 25  * @author zhouyy
 26  *
 27  */
 28 public class RSA {
 29 
 30     private static final String SIGN_TYPE_RSA = "RSA";
 31 
 32     private static final String SIGN_TYPE_RSA2 = "RSA2";
 33 
 34     private static final String SIGN_ALGORITHMS = "SHA1WithRSA";
 35 
 36     private static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
 37 
 38     private static final int DEFAULT_BUFFER_SIZE = 8192;
 39 
 40     /**
 41      * RSA/RSA2 生成签名
 42      * 
 43      * @param map
 44      *            包含 sign_type、privateKey、charset
 45      * @return
 46      * @throws Exception
 47      */
 48     public static String rsaSign(Map map) throws Exception {
 49         PrivateKey priKey = null;
 50         java.security.Signature signature = null;
 51         String signType = map.get("sign_type").toString();
 52         String privateKey = map.get("privateKey").toString();
 53         String charset = map.get("charset").toString();
 54         String content = getSignContent(map);
 55         map.put("content", content);
 56         System.out.println("请求参数生成的字符串为:" + content);
 57         if (SIGN_TYPE_RSA.equals(signType)) {
 58             priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA, new ByteArrayInputStream(privateKey.getBytes()));
 59             signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
 60         } else if (SIGN_TYPE_RSA2.equals(signType)) {
 61             priKey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA, new ByteArrayInputStream(privateKey.getBytes()));
 62             signature = java.security.Signature.getInstance(SIGN_SHA256RSA_ALGORITHMS);
 63         } else {
 64             throw new Exception("不是支持的签名类型 : : signType=" + signType);
 65         }
 66         signature.initSign(priKey);
 67 
 68         if (StringUtil.isEmpty(charset)) {
 69             signature.update(content.getBytes());
 70         } else {
 71             signature.update(content.getBytes(charset));
 72         }
 73 
 74         byte[] signed = signature.sign();
 75 
 76         return new String(Base64.encodeBase64(signed));
 77 
 78     }
 79 
 80     /**
 81      * 验签方法
 82      * 
 83      * @param content
 84      *            参数的合成字符串格式: key1=value1&key2=value2&key3=value3...
 85      * @param sign
 86      * @param publicKey
 87      * @param charset
 88      * @param signType
 89      * @return
 90      */
 91     public static boolean rsaCheck(Map map, String sign) throws Exception {
 92         java.security.Signature signature = null;
 93         String signType = map.get("sign_type").toString();
 94         String privateKey = map.get("privateKey").toString();
 95         String charset = map.get("charset").toString();
 96         String content = map.get("content").toString();
 97         String publicKey = map.get("publicKey").toString();
 98         System.out.println(">>验证的签名为:" + sign);
 99         System.out.println(">>生成签名的参数为:" + content);
100         PublicKey pubKey = getPublicKeyFromX509("RSA", new ByteArrayInputStream(publicKey.getBytes()));
101         if (SIGN_TYPE_RSA.equals(signType)) {
102             signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
103         } else if (SIGN_TYPE_RSA2.equals(signType)) {
104             signature = java.security.Signature.getInstance(SIGN_SHA256RSA_ALGORITHMS);
105         } else {
106             throw new Exception("不是支持的签名类型 : signType=" + signType);
107         }
108         signature.initVerify(pubKey);
109 
110         if (StringUtil.isEmpty(charset)) {
111             signature.update(content.getBytes());
112         } else {
113             signature.update(content.getBytes(charset));
114         }
115 
116         return signature.verify(Base64.decodeBase64(sign.getBytes()));
117     }
118 
119     public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, InputStream ins) throws Exception {
120         if (ins == null || StringUtil.isEmpty(algorithm)) {
121             return null;
122         }
123 
124         KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
125 
126         byte[] encodedKey = readText(ins).getBytes();
127 
128         encodedKey = Base64.decodeBase64(encodedKey);
129 
130         return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
131     }
132 
133     public static PublicKey getPublicKeyFromX509(String algorithm, InputStream ins) throws Exception {
134         KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
135 
136         StringWriter writer = new StringWriter();
137         io(new InputStreamReader(ins), writer, -1);
138 
139         byte[] encodedKey = writer.toString().getBytes();
140 
141         encodedKey = Base64.decodeBase64(encodedKey);
142 
143         return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
144     }
145 
146     /**
147      * 把参数合成成字符串
148      * 
149      * @param sortedParams
150      * @return
151      */
152     public static String getSignContent(Map<String, String> sortedParams) {
153         StringBuffer content = new StringBuffer();
154         // app_id,method,charset,sign_type,version,bill_type,timestamp,bill_date
155         String[] sign_param = sortedParams.get("sign_param").split(",");// 生成签名所需的参数
156         List<String> keys = new ArrayList<String>();
157         for (int i = 0; i < sign_param.length; i++) {
158             keys.add(sign_param[i]);
159         }
160         Collections.sort(keys);
161         int index = 0;
162         for (int i = 0; i < keys.size(); i++) {
163             String key = keys.get(i);
164             /*if ("biz_content".equals(key)) {
165                 content.append(
166                         (index == 0 ? "" : "&") + key + "={\"bill_date\":\"" + sortedParams.get("bill_date") + "\",")
167                         .append("\"bill_type\":\"" + sortedParams.get("bill_type") + "\"}");
168                 index++;
169             } else {*/
170             String value = sortedParams.get(key);
171             if (StringUtil.isNotEmpty(key) && StringUtil.isNotEmpty(value)) {
172                 content.append((index == 0 ? "" : "&") + key + "=" + value);
173                 index++;
174             }    
175 //            }
176         }
177         return content.toString();
178     }
179 
180     private static String readText(InputStream ins) throws IOException {
181         Reader reader = new InputStreamReader(ins);
182         StringWriter writer = new StringWriter();
183 
184         io(reader, writer, -1);
185         return writer.toString();
186     }
187 
188     private static void io(Reader in, Writer out, int bufferSize) throws IOException {
189         if (bufferSize == -1) {
190             bufferSize = DEFAULT_BUFFER_SIZE >> 1;
191         }
192 
193         char[] buffer = new char[bufferSize];
194         int amount;
195 
196         while ((amount = in.read(buffer)) >= 0) {
197             out.write(buffer, 0, amount);
198         }
199     }
200 
201 }

 

posted @ 2017-04-18 16:07  _万古如长夜  阅读(28084)  评论(0编辑  收藏  举报