网站首页 > 技术文章 正文
一、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
原文:
https://www.cnblogs.com/cicada-smile/p/11711358.html
首发微信公众号:知了一笑
猜你喜欢
- 2025-07-01 Java 如何加载带密码的 PCKS8 PEM 私钥
- 2025-07-01 犯罪啊 2.8万台路由器居然共用一把RSA密钥
- 2025-07-01 HTTPS全站加密时代 网宿推证书优选方案
- 2025-07-01 如何在 Windows 11 或 10 上使用 Winget 安装 OpenSSH
- 2025-07-01 网络篇:朋友面试之https认证加密过程
- 2025-07-01 如何安全管理SSH密钥以防止服务器被入侵
- 2025-07-01 在 Windows 10 上实现免密码 SSH 登录
- 2025-07-01 HTTPS的加密过程是怎样的?(https加密和解密的过程)
- 2025-07-01 Linux系统实现SSH安全免密登录的设置与管理
- 2025-07-01 Burpsuit插件开发之RSA加解密(burpsuite安装插件)
你 发表评论:
欢迎- 590℃几个Oracle空值处理函数 oracle处理null值的函数
- 583℃Oracle分析函数之Lag和Lead()使用
- 570℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 568℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 563℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 555℃【数据统计分析】详解Oracle分组函数之CUBE
- 541℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 536℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端懒加载 (49)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)