话不多说,代码如下

 package com.syl.test_key;

 import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap; /**
* Created by 孙义朗 on 2017/11/24 0024.
*/
@Slf4j
public class KeyUtil {
public static final String KEY_ALGORTHM = "RSA";//
public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
public static final String PUBLIC_KEY = "RSAPublicKey";//公钥
public static final String PRIVATE_KEY = "RSAPrivateKey";//私钥 //map对象中存放公私钥(初始化,生成一对公钥和私钥) 1
public static Map<String, Object> initKey() throws Exception {
//获得对象 KeyPairGenerator 参数 RSA 1024个字节
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORTHM);
keyPairGen.initialize(1024);
//通过对象 KeyPairGenerator 获取对象KeyPair
KeyPair keyPair = keyPairGen.generateKeyPair(); //通过对象 KeyPair 获取RSA公私钥对象RSAPublicKey RSAPrivateKey
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
//公私钥对象存入map中
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
} /**
* 获得公钥 2
*/
public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
//获得map中的公钥对象 转为key对象
Key key = (Key) keyMap.get(PUBLIC_KEY);
//编码返回字符串 2.1
return encryptBASE64(key.getEncoded());
} //编码返回字符串 2.1(3.1)
public static String encryptBASE64(byte[] key) throws Exception {
return (new BASE64Encoder()).encodeBuffer(key);
} /**
* 获得私钥 3
*/
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
//获得map中的私钥对象 转为key对象
Key key = (Key) keyMap.get(PRIVATE_KEY);
//编码返回字符串 3.1
return encryptBASE64(key.getEncoded());
} /**
* 根据私钥,生成数字签名 4
*/
public static String getSign(TreeMap<String, Object> map, String privateKey) {
try {
log.info("****** privateKey : " + privateKey); //获取待签名的字符串 4.1
String result = getValue(map);
log.info("****** 参与签名的字符串为:[" + result + "]");
//信息加密,生成数字签名 4.2
return KeyUtil.sign(result.getBytes("utf-8"), privateKey);
} catch (Exception e) {
log.info("****** 签名异常", e);
return "";
}
} //获取待签名的字符串 4.1(5.1)
public static String getValue(TreeMap<String, Object> map) throws Exception {
log.info("****** 加签字符串:[" + map.toString() + "]");
map.remove("sign");// 移除上送上来的sign字段
StringBuilder sb = new StringBuilder();
Iterator<Map.Entry<String, Object>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Object> entry = iter.next();
sb.append(entry.getValue() == null ? "" : entry.getValue());
}
String result = sb.toString(); return result;
} //用私钥对需要加密的信息加密 4.2
public static String sign(byte[] data, String privateKey) throws Exception {
//解密私钥
byte[] keyBytes = Base64.decodeBase64(privateKey);
//构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
//指定加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
//取私钥匙对象
PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateKey2);
signature.update(data); return Base64.encodeBase64String(signature.sign());
} /**
* 用公钥,校验签名 5
*/
public static boolean vertifySign(TreeMap<String, Object> map, String sign, String publicKey) {
try {
log.info("****** publicKey : " + publicKey); //获取待校验的字符串 5.1
String result = getValue(map);
log.info("****** 参与验签的字符串为:[" + result + "]");
//校验数字签名 5.2
return KeyUtil.verify(result.getBytes("utf-8"), publicKey, sign);
} catch (UnsupportedEncodingException e) {
log.error("****** 校验签名异常", e);
return false;
} catch (Exception e) {
log.error("****** 校验签名异常", e);
return false;
}
} //校验数字签名(校验签名使用) 5.2
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
//解密公钥
byte[] keyBytes = Base64.decodeBase64(publicKey);
//构造X509EncodedKeySpec对象
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
//指定加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
//取公钥匙对象
PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicKey2);
signature.update(data);
//验证签名是否正常
return signature.verify(Base64.decodeBase64(sign));
} //解码返回byte
public static byte[] decryptBASE64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
} }

KeyUtil

测试类

 package com.syl.test_key;

 import java.util.Map;
import java.util.TreeMap; /**
* Created by 孙义朗 on 2017/11/24 0024.
*/
public class TestKey {
public static void main(String[] args) throws Exception {
//新建一个需要加签的信息
TreeMap<String, Object> treeMap = new TreeMap();
treeMap.put("name", "syl");
treeMap.put("age", 18); //map对象中存放公私钥
Map<String, Object> keyMap = KeyUtil.initKey(); //获得公钥和私钥
String publicKey = KeyUtil.getPublicKey(keyMap);
String privateKey = KeyUtil.getPrivateKey(keyMap); //获取签名
String sign = KeyUtil.getSign(treeMap, privateKey); //验证签名
boolean flag = KeyUtil.vertifySign(treeMap, sign, publicKey);
if (flag) {
System.out.println("验证成功!");
} else {
System.err.println("验证失败");
}
}
}

TestKey

控制台输出

java POST 传值 加签 验证的更多相关文章

  1. RSA体系 c++/java相互进行加签验签--转

    在web开发中,采用RSA公钥密钥体系自制ukey,文件证书登陆时,普遍的做法为:在浏览器端采用c++ activex控件,使用 c++的第三库openssl进行RAS加签操作,在服务器端采用java ...

  2. Java Http接口加签、验签操作方法

    1.业务背景 最近接触了一些电商业务,发现在处理电商业务接口时,比如淘宝.支付类接口,接口双方为了确保数据参数在传输过程中未经过篡改,都需要对接口数据进行加签,然后在接口服务器端对接口参数进行验签,确 ...

  3. Java实现RSA密钥对并在加解密、加签验签中应用的实例

    一.项目结构 二.代码具体实现 1.密钥对生成的两种方式:一种生成公钥私文件,一种生成公钥私串 KeyPairGenUtil.java package com.wangjinxiang.genkey. ...

  4. 记一次Java加密加签算法到php的坑

    此文为本人原创首发于 http://www.35coder.com/convert_encryption_codes_to_php/. 写代码的经历中,总少不了与外部的程序对接,一旦有这样的事,往往周 ...

  5. java RSA 加签验签【转】

    引用自: http://blog.csdn.net/wangqiuyun/article/details/42143957/ java RSA 加签验签 package com.testdemo.co ...

  6. Http请求加签、验证操作

    加签.验签的作用 常见的http请求交互过程中,请求参数通过url或者request body等形式传输.但是由于http请求的开放性,使得请求参数很容易被拦截篡改.因此,需要对请求参数进行加签,然后 ...

  7. iOS下使用SHA1WithRSA算法加签源码

    首先了解一下几个相关概念,以方便后面遇到的问题的解决: RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的,RSA就是取自他们三个人的名字.算法基于一个数 ...

  8. RSA加密解密及RSA加签验签

    RSA安全性应用场景说明 在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解 ...

  9. Java中常用加减密方式

    1.加密概述: 加密就是是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使以获得了加密的信息,但因不知解密方式,仍无法了解信息的内容.大体上又分为双向加密和单向加密. 2.单项加密 2.1.概 ...

随机推荐

  1. 楊輝三角C#版

    class Program { static void Main(string[] args) { Console.WriteLine("please input a number:&quo ...

  2. C#读取Excel的数据,并且以混合模式读取,防止数据类型变更

    /// <summary> /// Read Excel to DataSet /// </summary> /// <param name="filename ...

  3. AJAX方式调用百度天气

    后台代码: [HttpPost] public string AjaxWeather() { string CityName = string.IsNullOrEmpty(Request.Form[& ...

  4. 构建针对 iOS 和 Android 的原生扩展

    第一部分:音量控制入门 http://www.adobe.com/cn/devnet/air/articles/building-ane-ios-android-pt1.html 第二部分: 开发 A ...

  5. leecode刷题(12)-- 整数反转

    leecode刷题(12)-- 整数反转 整数反转 描述: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: - ...

  6. php.ini中safe_mode开启之后对于PHP系统函数的影响

    safe_mode是提供一个基本安全的共享环境. 在一个多用户共享的phpweb服务器上,当这台服务器开启了safe_mode模式,有以下函数将会受到影响. 首先,以下尝试访问文件系统的函数将会被限制 ...

  7. git恢复到上次提交

    4个区 5种状态 未修改(Origin) 已修改(Modified) 已暂存(Staged) 已提交(Committed) 已推送(Pushed) 检查修改 已修改,未暂存(检查工作区与暂存区间的差异 ...

  8. 2016级算法第四次上机-E.Bamboo and the Ancient Spell

    Bamboo and the Ancient Spell 分析 可能英文读题难度比较大,但是只要看到全大写的 "THE LONGEST COMMON SUBSEQUENCE !"应 ...

  9. html5兼容问题

    1.html5对于ie9一下的版本不支持,所以我们可以添加(你可以下载至本地): <!--[if lt IE 9]> <script src="http://cdn.sta ...

  10. mocha测试框架

    中文翻译文档:https://www.jianshu.com/p/9c78548caffa 阮一峰:http://www.ruanyifeng.com/blog/2015/12/a-mocha-tut ...