java POST 传值 加签 验证

 话不多说,代码如下

  1 package com.syl.test_key;
  2 
  3 import lombok.extern.slf4j.Slf4j;
  4 import org.apache.commons.codec.binary.Base64;
  5 import sun.misc.BASE64Decoder;
  6 import sun.misc.BASE64Encoder;
  7 
  8 import java.io.UnsupportedEncodingException;
  9 import java.security.*;
 10 import java.security.interfaces.RSAPrivateKey;
 11 import java.security.interfaces.RSAPublicKey;
 12 import java.security.spec.PKCS8EncodedKeySpec;
 13 import java.security.spec.X509EncodedKeySpec;
 14 import java.util.HashMap;
 15 import java.util.Iterator;
 16 import java.util.Map;
 17 import java.util.TreeMap;
 18 
 19 /**
 20  * Created by 孙义朗 on 2017/11/24 0024.
 21  */
 22 @Slf4j
 23 public class KeyUtil {
 24     public static final String KEY_ALGORTHM = "RSA";//
 25     public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
 26     public static final String PUBLIC_KEY = "RSAPublicKey";//公钥
 27     public static final String PRIVATE_KEY = "RSAPrivateKey";//私钥
 28 
 29     //map对象中存放公私钥(初始化,生成一对公钥和私钥)   1
 30     public static Map<String, Object> initKey() throws Exception {
 31         //获得对象 KeyPairGenerator 参数 RSA 1024个字节
 32         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORTHM);
 33         keyPairGen.initialize(1024);
 34         //通过对象 KeyPairGenerator 获取对象KeyPair
 35         KeyPair keyPair = keyPairGen.generateKeyPair();
 36 
 37         //通过对象 KeyPair 获取RSA公私钥对象RSAPublicKey RSAPrivateKey
 38         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
 39         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
 40         //公私钥对象存入map中
 41         Map<String, Object> keyMap = new HashMap<String, Object>(2);
 42         keyMap.put(PUBLIC_KEY, publicKey);
 43         keyMap.put(PRIVATE_KEY, privateKey);
 44         return keyMap;
 45     }
 46 
 47     /**
 48      * 获得公钥   2
 49      */
 50     public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
 51         //获得map中的公钥对象 转为key对象
 52         Key key = (Key) keyMap.get(PUBLIC_KEY);
 53         //编码返回字符串   2.1
 54         return encryptBASE64(key.getEncoded());
 55     }
 56 
 57     //编码返回字符串   2.1(3.1)
 58     public static String encryptBASE64(byte[] key) throws Exception {
 59         return (new BASE64Encoder()).encodeBuffer(key);
 60     }
 61 
 62     /**
 63      * 获得私钥   3
 64      */
 65     public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
 66         //获得map中的私钥对象 转为key对象
 67         Key key = (Key) keyMap.get(PRIVATE_KEY);
 68         //编码返回字符串   3.1
 69         return encryptBASE64(key.getEncoded());
 70     }
 71 
 72 
 73     /**
 74      * 根据私钥,生成数字签名   4
 75      */
 76     public static String getSign(TreeMap<String, Object> map, String privateKey) {
 77         try {
 78             log.info("****** privateKey : " + privateKey);
 79 
 80             //获取待签名的字符串   4.1
 81             String result = getValue(map);
 82             log.info("****** 参与签名的字符串为:[" + result + "]");
 83             //信息加密,生成数字签名   4.2
 84             return KeyUtil.sign(result.getBytes("utf-8"), privateKey);
 85         } catch (Exception e) {
 86             log.info("****** 签名异常", e);
 87             return "";
 88         }
 89     }
 90 
 91     //获取待签名的字符串   4.1(5.1)
 92     public static String getValue(TreeMap<String, Object> map) throws Exception {
 93         log.info("****** 加签字符串:[" + map.toString() + "]");
 94         map.remove("sign");// 移除上送上来的sign字段
 95         StringBuilder sb = new StringBuilder();
 96         Iterator<Map.Entry<String, Object>> iter = map.entrySet().iterator();
 97         while (iter.hasNext()) {
 98             Map.Entry<String, Object> entry = iter.next();
 99             sb.append(entry.getValue() == null ? "" : entry.getValue());
100         }
101         String result = sb.toString();
102 
103         return result;
104     }
105 
106     //用私钥对需要加密的信息加密   4.2
107     public static String sign(byte[] data, String privateKey) throws Exception {
108         //解密私钥
109         byte[] keyBytes = Base64.decodeBase64(privateKey);
110         //构造PKCS8EncodedKeySpec对象
111         PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
112         //指定加密算法
113         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
114         //取私钥匙对象
115         PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
116         //用私钥对信息生成数字签名
117         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
118         signature.initSign(privateKey2);
119         signature.update(data);
120 
121         return Base64.encodeBase64String(signature.sign());
122     }
123 
124     /**
125      * 用公钥,校验签名   5
126      */
127     public static boolean vertifySign(TreeMap<String, Object> map, String sign, String publicKey) {
128         try {
129             log.info("****** publicKey : " + publicKey);
130 
131             //获取待校验的字符串   5.1
132             String result = getValue(map);
133             log.info("****** 参与验签的字符串为:[" + result + "]");
134             //校验数字签名   5.2
135             return KeyUtil.verify(result.getBytes("utf-8"), publicKey, sign);
136         } catch (UnsupportedEncodingException e) {
137             log.error("****** 校验签名异常", e);
138             return false;
139         } catch (Exception e) {
140             log.error("****** 校验签名异常", e);
141             return false;
142         }
143     }
144 
145     //校验数字签名(校验签名使用)   5.2
146     public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
147         //解密公钥
148         byte[] keyBytes = Base64.decodeBase64(publicKey);
149         //构造X509EncodedKeySpec对象
150         X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
151         //指定加密算法
152         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
153         //取公钥匙对象
154         PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);
155 
156         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
157         signature.initVerify(publicKey2);
158         signature.update(data);
159         //验证签名是否正常
160         return signature.verify(Base64.decodeBase64(sign));
161     }
162 
163 
164     //解码返回byte
165     public static byte[] decryptBASE64(String key) throws Exception {
166         return (new BASE64Decoder()).decodeBuffer(key);
167     }
168 
169 }
KeyUtil

测试类

 1 package com.syl.test_key;
 2 
 3 import java.util.Map;
 4 import java.util.TreeMap;
 5 
 6 /**
 7  * Created by 孙义朗 on 2017/11/24 0024.
 8  */
 9 public class TestKey {
10     public static void main(String[] args) throws Exception {
11         //新建一个需要加签的信息
12         TreeMap<String, Object> treeMap = new TreeMap();
13         treeMap.put("name", "syl");
14         treeMap.put("age", 18);
15 
16         //map对象中存放公私钥
17         Map<String, Object> keyMap = KeyUtil.initKey();
18 
19         //获得公钥和私钥
20         String publicKey = KeyUtil.getPublicKey(keyMap);
21         String privateKey = KeyUtil.getPrivateKey(keyMap);
22 
23         //获取签名
24         String sign = KeyUtil.getSign(treeMap, privateKey);
25 
26         //验证签名
27         boolean flag = KeyUtil.vertifySign(treeMap, sign, publicKey);
28         if (flag) {
29             System.out.println("验证成功!");
30         } else {
31             System.err.println("验证失败");
32         }
33     }
34 }
TestKey

控制台输出

原文地址:https://www.cnblogs.com/arrrrrya/p/7890972.html