• 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

    控制台输出

  • 相关阅读:
    Tomcatd断点调试Debug
    idea怎么部署Servlet
    ECMAScript基本语法——①与HTML的结合方式
    JavaScript简介
    程序员找工作,应该怎么应对面试官?
    你所未知的3种 Node.js 代码优化方式
    对 APM 用户的一次真实调查分析(上)
    Datadog Agent是啥?它消耗什么资源?
    Python 全栈开发 -- 开发环境篇
    成为运维界的「福尔摩斯」,你还需要3个帮手!
  • 原文地址:https://www.cnblogs.com/arrrrrya/p/7890972.html
Copyright © 2020-2023  润新知