数据安全管理:RSA加密算法,签名验签流程详解
本文源码:GitHub·点这里 || GitEE·点这里
一、RSA算法简介
1、加密解密
RSA加密是一种非对称加密,在公开密钥加密和电子商业中RSA被广泛使用。可以在不直接传递密钥的情况下,完成加解密操作。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。
2、签名验签
数字签名就是信息的来源添加一段无法被伪造的加密字符串,这段数字串作为对信息的来源真实性的一个有效证明。这个过程称为签名和验签。
二、场景描述
- 消息发送方:甲方,持有公钥
- 消息接收方:乙方,持有私钥
1、加密解密过程
(1)、乙方生成一对密钥即公钥和私钥,私钥不公开,乙方自己持有,公钥为公开,甲方持有。
(2)、乙方收到甲方加密的消息,使用私钥对消息进行解密,获取明文。
2、签名验签过程
(1)、乙方收到消息后,需要回复甲方,用私钥对回复消息签名,并将消息明文和消息签名回复甲方。
(2)、甲方收到消息后,使用公钥进行验签,如果验签结果是正确的,则证明消息是乙方回复的。
三、源代码实现
1、密钥字符串获取
- 代码生成
private static HashMap<String, String> getTheKeys() {HashMap<String, String> keyPairMap = new HashMap<String, String>();KeyPairGenerator keyPairGen = null;try {keyPairGen = KeyPairGenerator.getInstance("RSA");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}// 密钥大小:1024 位keyPairGen.initialize(1024);KeyPair keyPair = keyPairGen.generateKeyPair();String publicKey = printBase64Binary(keyPair.getPublic().getEncoded());String privateKey = printBase64Binary(keyPair.getPrivate().getEncoded());keyPairMap.put("publicKey", publicKey);keyPairMap.put("privateKey", privateKey);return keyPairMap ;
}
- 读取文件
文件位置
public static final String PUB_KEY = "rsaKey/public.key" ;
public static final String PRI_KEY = "rsaKey/private.key" ;
文件加载
public static String getKey (String keyPlace) throws Exception {BufferedReader br= null;try {br= new BufferedReader(new InputStreamReader(RsaCryptUtil.class.getClassLoader().getResourceAsStream(keyPlace)));String readLine= null;StringBuilder keyValue = new StringBuilder();while((readLine= br.readLine())!=null){if(!(readLine.charAt(0)=='-')){keyValue.append(readLine);}}return keyValue.toString();} catch (Exception e) {throw new Exception("RSA密钥读取错误",e) ;} finally{if (br != null) {try {br.close();} catch (Exception e) {System.out.println("密钥读取流关闭异常");}}}
}
2、公钥和私钥
- 公钥字符串生成公钥
public static RSAPublicKey createPublicKey(String publicKeyValue) throws Exception {try {byte[] buffer = DatatypeConverter.parseBase64Binary(publicKeyValue);KeyFactory keyFactory = KeyFactory.getInstance("RSA");X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);return (RSAPublicKey) keyFactory.generatePublic(keySpec);} catch (Exception e) {throw new Exception("公钥创建失败", e);}
}
- 私钥字符串生成私钥
public static RSAPrivateKey createPrivateKey(String privateKeyValue) throws Exception {try {byte[] buffer = javax.xml.bind.DatatypeConverter.parseBase64Binary(privateKeyValue);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);KeyFactory keyFactory = KeyFactory.getInstance("RSA");return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);} catch (Exception e) {throw new Exception("私钥创建失败", e);}
}
3、加密和解密
- 公钥加密
public static String encrypt(RSAPublicKey publicKey, byte[] clearData) throws Exception {if (publicKey == null) {throw new Exception("加密公钥为空, 无法加密");}try {Cipher cipher = Cipher.getInstance("RSA") ;cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] output = cipher.doFinal(clearData);return printBase64Binary(output);} catch (Exception e) {throw new Exception("公钥加密失败",e);}
}
- 私钥解密
public static String decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception {if (privateKey == null) {throw new Exception("解密私钥为空, 无法解密");}try {Cipher cipher = Cipher.getInstance("RSA") ;cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] output = cipher.doFinal(cipherData);return new String(output);} catch (BadPaddingException e) {throw new Exception("私钥解密失败",e);}
}
4、签名和验签
- 私钥签名
public static String sign (String signData, PrivateKey privateKey) throws Exception {byte[] keyBytes = privateKey.getEncoded();PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey key = keyFactory.generatePrivate(keySpec);Signature signature = Signature.getInstance("MD5withRSA");signature.initSign(key);signature.update(signData.getBytes());return printBase64Binary(signature.sign());
}
- 公钥验签
public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {byte[] keyBytes = publicKey.getEncoded();X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey key = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance("MD5withRSA");signature.initVerify(key);signature.update(srcData.getBytes());return signature.verify(parseBase64Binary(sign));
}
5、编码和解码
/*** 字节数组转字符*/
public static String printBase64Binary(byte[] bytes) {return DatatypeConverter.printBase64Binary(bytes);
}
/*** 字符转字节数组*/
public static byte[] parseBase64Binary(String value) {return DatatypeConverter.parseBase64Binary(value);
}
6、测试代码块
- 密钥生成测试
public static void testCreateKey () throws Exception {HashMap<String, String> map = RsaCryptUtil.getTheKeys();String privateKeyStr=map.get("privateKey");String publicKeyStr=map.get("publicKey");System.out.println("私钥:"+privateKeyStr);System.out.println("公钥:"+publicKeyStr);//消息发送方String originData="cicada-smile";System.out.println("原文:"+originData);String encryptData = RsaCryptUtil.encrypt(RsaCryptUtil.createPublicKey(publicKeyStr),originData.getBytes());System.out.println("加密:"+encryptData);//消息接收方String decryptData=RsaCryptUtil.decrypt(RsaCryptUtil.createPrivateKey(privateKeyStr),RsaCryptUtil.parseBase64Binary(encryptData));System.out.println("解密:"+decryptData);
}
- 密钥读取测试
public static void testReadKey () throws Exception {String value = getKey("rsaKey/public.key");System.out.println(value);String privateKeyStr = getKey(RsaCryptUtil.PRI_KEY) ;String publicKeyStr = getKey(RsaCryptUtil.PUB_KEY) ;//消息发送方String originData="cicada-smile";System.out.println("原文:"+originData);String encryptData = RsaCryptUtil.encrypt(RsaCryptUtil.createPublicKey(publicKeyStr),originData.getBytes());System.out.println("加密:"+encryptData);//消息接收方String decryptData=RsaCryptUtil.decrypt(RsaCryptUtil.createPrivateKey(privateKeyStr),RsaCryptUtil.parseBase64Binary(encryptData));System.out.println("解密:"+decryptData);
}
- 签名验签测试
public static void testSignVerify () throws Exception {String signData = "cicada-smile" ;String privateKeyStr = getKey(RsaCryptUtil.PRI_KEY) ;String publicKeyStr = getKey(RsaCryptUtil.PUB_KEY) ;String signValue = sign(signData,RsaCryptUtil.createPrivateKey(privateKeyStr)) ;boolean flag = verify(signData,RsaCryptUtil.createPublicKey(publicKeyStr),signValue);System.out.println("原文:"+signData);System.out.println("签名:"+signValue);System.out.println("验签:"+flag);
}
四、源代码地址
GitHub·地址
https://github.com/cicadasmile
GitEE·地址
https://gitee.com/cicadasmile
数据安全管理:RSA加密算法,签名验签流程详解相关推荐
- 如何使用RSA 对数据加解密和签名验签?一篇文章带你搞定
点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 三分割据纡筹策,万古云霄一羽毛. ...
- 密码技术应用--RSA文件签名验签
记录一下对一些稍大文件进行RSA签名验签的实现,这里只列出了核心代码,其他不涉及的代码或者有任何疑问可以查看我之前写的密码技术专题博客 /* 函数名: rsaSignrsa 签名算法实现对文件的签名 ...
- 叙述无保密机制的rsa签名过程_安全系列之——RSA的公钥私钥有多少人能分的清楚?RSA的签名验签与加密解密如何使用公私钥?...
在对接很多的互联网公司的开发平台时,这些互联网公司未来自身平台的安全,都会需要调用方签名确认调用方的身份是合法的,同时未来信息网络传输的安全可能还需要加密解密.比如对接支付宝.微信开放平台时,需要配置 ...
- 工银e生活开发脱坑日志(1)RSA密钥签名验签windows环境下配置
**环境配置:**阿里云 windows 2012 R2,WAMPSERVER 3.0.17集成环境 **入坑问题:**RSA2密钥对的生产及验签,产生报错信息:Warning: openssl_ve ...
- The Elliptic Curve Digital Signature Algorithm(ECDSA)学习之路 - 签名验签流程
前言 本文档主要基于规范<ANSI-X962-2005>进行学习理解.该标准主要定义了使用ECDSA算法对数据进行保护的数字签名的产生和验证方法. ECDSA应该与某个已经验证过的Hash ...
- php流调签名,微信接口签名及调用流程详解 - 黎明互联-官方博客 - 黎明互联 - 区块链培训,PHP培训,IT培训,职业技能培训,追求极致!改变您的职业生涯!...
在调用微信接口的时候无论是支付还是现金红包等等接口都会用到接口的加密和校验,微信的很多数据签名和调用规则其实都是一样的,首先构建原始数据,然后根据规则去除空值和签名方式(如果与的话),接下来案子点排序 ...
- 微信接口签名及调用流程详解
在调用微信接口的时候无论是支付还是现金红包等等接口都会用到接口的加密和校验,微信的很多数据签名和调用规则其实都是一样的,首先构建原始数据,然后根据规则去除空值和签名方式(如果与的话),接下来案子点排序 ...
- 大数据平台框架、组件以及处理流程详解
数据产品和数据密不可分作为数据产品经理理解数据从产生.存储到应用的整个流程,以及大数据建设需要采用的技术框架Hadoop是必备的知识清单,以此在搭建数据产品时能够从全局的视角理解从数据到产品化的价值. ...
- RSA密钥生成、加密解密、数据签名验签
公钥.私钥生成 准备工作,基础的帮助类 使用java代码生成公钥私钥 使用openssl生成公钥私钥 加解密 数据签名及验签 数据加解密及签名验签测试 注意项 公钥.私钥生成 准备工作,基础的帮助类 ...
最新文章
- 《第一行代码》学习笔记18-广播接收器Broadcast_Receiver(1)
- UI1_UIView层操作
- java访问方法修饰词四个_java中的四个修饰词(访问权限)
- linux多路径配置
- 设计模式 ( 六 ) 建造者模式
- Hexo + GitHub搭建个人博客 --- Standard Edition
- python3 多线程爬去mzitu图片
- CISCO路由基本配置命令
- 2020华师大个人考研总结
- 中企海外周报 | 银联业务拓展到171个国家和地区;徐工集团向非洲客户提供定制化设备...
- 物理专业要用的计算机语言,16岁被保送清华,本科毕业进麻省理工读博,现开发Taichi爆红网络...
- Java基础(自己总结)
- [Swift]LeetCode611. 有效三角形的个数 | Valid Triangle Number
- 斧子演示(AxeSlide):新时期,新用法
- 【Linux】一些命令
- 大厂争先成立的 “开源办公室” 有啥门道?
- Java实现ATM银行模拟系统(含完整代码)
- 朴素贝叶斯分类器之分类实操
- 修改npm全局安装包的位置路径
- C++之solmyr小品文