非对称加密实战(一):JDK生成keystore获取公钥私钥及代码验证【附源码】

news/2024/10/23 9:40:30/

目录

  • 使用说明
    • 非对称加密
    • 生成keystore文件
  • 公钥私钥互相解密
    • 获取fd-alias.keystore中的公钥私钥
    • 使用生成公钥私钥进行解密
  • 源码地址

使用说明

非对称加密

非对称加密算法主要有:RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)。下面例子中使用的就是RSA算法。

特点:非对称加密算法比对称加密算法慢数千倍,但在保护通信安全方面,非对称加密算法却具有对称密码难以企及的优势。

理解:非对称加密需要两把密钥:公钥和私钥,他们是一对,如果用公钥对数据加密,那么只能用对应的私钥解密。如果用私钥对数据加密,只能用对应的公钥进行解密。因为加密和解密用的是不同的密钥,所以称为非对称加密。

私钥加密---------》公钥解密
公钥加密---------》私钥解密
案例:
       为了保证安全:不允许中间第三方来截取篡改数据,生成唯一的公钥私钥。双方就需要各自生成自己的公钥私钥,并且发送给对方。
如:
      客户端发请求到服务端,需要拿着自己的公钥发送过去,而服务端收到后,拿着对应的私钥进行解密,解密成功后,进行下一环节。
如果在中间被第三方拦截到,篡改内容,服务端没有对应的公钥,服务端则解析失败。

生成keystore文件

需要进入jdk的bin目录下,找到keytool.exe

.\keytool.exe

在这里插入图片描述
查看生成密钥对帮助说明

 .\keytool.exe -genkeypair -help

在这里插入图片描述
输入命令生成自己的keystore文件

.\keytool.exe -genkeypair -alias fd-alias -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore D:\sumscope\MyCode\cer\fd-alias.keystore -storepass 123456

在这里插入图片描述
查看自己的密钥库

 .\keytool.exe -list -rfc -keystore D:\sumscope\MyCode\cer\fd-alias.keystore

在这里插入图片描述
生成文件
在这里插入图片描述

公钥私钥互相解密

获取fd-alias.keystore中的公钥私钥

package com.springweb.utils;import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;/*** 从证书获取 公钥和私钥* @author admin* @date 2022/1/7*/
public class ReadKeyStoreUtils {/*** Java密钥库(Java Key Store,JKS)KEY_STORE*/public static final String KEY_STORE = "JKS";public static final String X509 = "X.509";/*** BASE64解密* @param key* @return* @throws Exception*/public static byte[] decryptBASE64(String key) throws Exception {return(new BASE64Decoder()).decodeBuffer(key);}/*** BASE64加密* @param key* @return* @throws Exception*/public static String encryptBASE64(byte[] key) throws Exception {return(new BASE64Encoder()).encodeBuffer(key).replace("\r","").replace("\n","");}/*** 获得KeyStore** @param keyStorePath* @param password* @return* @throws Exception*/private static KeyStore getKeyStore(String keyStorePath, String password)throws Exception {FileInputStream is = new FileInputStream(keyStorePath);KeyStore ks = KeyStore.getInstance(KEY_STORE);ks.load(is, password.toCharArray());is.close();return ks;}/*** 由KeyStore获得私钥** @param keyStorePath* @param alias* @param storePass* @return*/private static PrivateKey getPrivateKey(String keyStorePath, String alias, String storePass, String keyPass) throws Exception {KeyStore ks = getKeyStore(keyStorePath, storePass);PrivateKey key = (PrivateKey) ks.getKey(alias, keyPass.toCharArray());return key;}/*** 由Certificate获得公钥** @param keyStorePath KeyStore路径* @param alias        别名* @param storePass    KeyStore访问密码*/private static PublicKey getPublicKey(String keyStorePath, String alias, String storePass) throws Exception {KeyStore ks = getKeyStore(keyStorePath, storePass);PublicKey key = ks.getCertificate(alias).getPublicKey();return key;}/*** 从KeyStore中获取公钥,并经BASE64编码** @param keyStorePath* @param alias* @param storePass*/public static String getStrPublicKey(String keyStorePath, String alias, String storePass) throws Exception {PublicKey key = getPublicKey(keyStorePath, alias, storePass);String strKey = encryptBASE64(key.getEncoded());return strKey;}/*** 获取经BASE64编码后的私钥** @param keyStorePath* @param alias* @param storePass* @param keyPass* @return* @throws Exception* @author 奔跑的蜗牛*/public static String getStrPrivateKey(String keyStorePath, String alias, String storePass, String keyPass) throws Exception {PrivateKey key = getPrivateKey(keyStorePath, alias, storePass, keyPass);String strKey = encryptBASE64(key.getEncoded());return strKey;}public static void main(String[] args) throws Exception {String keyStorePath = "D:\\sumscope\\MyCode\\cer\\fd-alias.keystore";String strPublicKey = getStrPublicKey(keyStorePath, "fd-alias", "123456");System.out.println("公钥:"+strPublicKey);String strPrivateKey = getStrPrivateKey(keyStorePath, "fd-alias", "123456", "123456");System.out.println("私钥:"+strPrivateKey);}}

结果:
在这里插入图片描述

使用生成公钥私钥进行解密

上面生成的公钥私钥需要保留,在这里需要使用到

package com.springweb.utils;import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher;
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.Map;public class RSAEncrypt {public static void main(String[] args) throws Exception {testAll();}public static void test() throws Exception {//生成公钥和私钥Map<String, String> keyMap = new HashMap<>();keyMap.put("publicKey", "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEXr8P0dlvpZRhcKSkKgfzSRA3TpH8RfZc7b529PeiaRQGm7cXlath5w0Nj1gs6jZWSzltcf7SIdMEkpxTX4/xbXt8v/87L7DdicGOt4+VVh6NOrqB9HhNqeEtGRMv+DAHg6zij3uA+YCNA40Oretojjf4v51QSsvfQv6W4DWhTQIDAQAB");keyMap.put("privateKey", "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMRevw/R2W+llGFwpKQqB/NJEDdOkfxF9lztvnb096JpFAabtxeVq2HnDQ2PWCzqNlZLOW1x/tIh0wSSnFNfj/Fte3y//zsvsN2JwY63j5VWHo06uoH0eE2p4S0ZEy/4MAeDrOKPe4D5gI0DjQ6t62iON/i/nVBKy99C/pbgNaFNAgMBAAECgYBRAjUXtZ5ZrJkVyX5iKuS0vINwDX2z8Li9hWZ5dH1kBq04PKy/kgLtlH+SBHx/qu9XkhjSyaAx17pRvJm420dpvJy7T9GHlQ9bOVxaKNxsodxokERu69+YqHmfFrRG7UjfVup4gqU1SRdBaRWmMhY7QwTCQgV5IOJG/gDICa6LkQJBAOJoCZGz3d+oKsv1GRpmtUMrACyuK20jAC0G8wkNyn80UF8eyX9C2axSFX55Ha94YSkLGC5hzxlkHvT1COaRmVsCQQDeCaQSoypYfYDaSPXi8IpXHgY2QzB2ABP0SjqDlcMV+pK/G4e5i8ptmQZOlYUgkjAGEeXX8sq5iQHJ7hNZXYh3AkEArEsB5Thcw0RFdTrK5LV+gWPq2RWeBIqbKqjcMGqnTBAyjYBvVII6BhHdO4bN2WehgMtplnpmUOtJR55lLJlmewJAEcDDlZnmMN0YCFv9DQAej4ifBoeowEaRUd79frfiuUcnpJAW8gbzUIADuRTLaCdIH7QepH2NJ/iEZBjdAzAvUQJAW0jhWNcfM+2eMuUNvjRCLlKnoJN8yhY0Sl+oPP1ImEbFoWSh/kIa4dZep8FDSrChq8FTPaK0DgUWno893QMszA==");String publicKey = keyMap.get("publicKey");String privateKey = keyMap.get("privateKey");System.out.println("公钥:"+publicKey);System.out.println("私钥:"+privateKey);// 原始字符串String message = "我是测试 原始内容";System.out.println("原始数据:"+message);long startTime = System.currentTimeMillis();for (int i=0;i<10;i++){String messageEn = publicKeyEncrypt(message, publicKey);System.out.println("公钥加密后内容:" + messageEn);String messageDe = privateKeyDecrypt(messageEn, privateKey);System.out.println("私钥解密后内容:" + messageDe);}long endTime = System.currentTimeMillis();System.out.println(endTime - startTime);}/*** 公加私解* 私加公解* @throws Exception*/public static void testAll() throws Exception {//生成公钥和私钥Map<String, String> keyMap = new HashMap<>();keyMap.put("publicKey", "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmqgoIV7+9E2JI7FHFPyEiFzaCufvP0JNIqR3HoytzME9Nt1c3ykMClOpgO8drsZILfAx/rXLdsWC4jjKORWSFDJ+UEqD6y8qOyzFwK3sRR9zdS7rWxdl62IfsdQdHptlygQ/MC09a8koXjbUdiqadf0NkjMiMaZfnHoqWbWmttQIDAQAB");keyMap.put("privateKey", "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKaqCghXv70TYkjsUcU/ISIXNoK5+8/Qk0ipHcejK3MwT023VzfKQwKU6mA7x2uxkgt8DH+tct2xYLiOMo5FZIUMn5QSoPrLyo7LMXArexFH3N1LutbF2XrYh+x1B0em2XKBD8wLT1rySheNtR2Kpp1/Q2SMyIxpl+ceipZtaa21AgMBAAECgYBuxJJ4awGXQ5vOBapvIv79blofVkbDHsfUwfl15r+JBjGe4FyKStZwj9KZ9QEcVV9QXLjd3sR6DVrQLknxfrNIGtKnw15tKrNvec+nt/TqKXlY1sQThouBGmISLl2kTe0mIdOdVfJ5bGpe8miH73/3C6eGMnCWfcT3/acLYP++vQJBAOBgIggoFqZlQi0IOQhC7tM8VeMG/D8ie8gJK2O86Q72elz/WLTs4ttIQZLDxEu3buFs5PUTpDnP9cuXRu3EF/cCQQC+J5R4ZrQZEr6yIyoal+3NzpyIE42KfOgYrOZc2E9BhaX2vVT+xyPhOARfG5TOiU0BNXiy3H9MGG24cj/e13SzAkBzEnqBqmWrYuUkiUIOrZ0kcp4tt+hoTLwk5Cb/mOQCC4DH7yFEcPULtywCJCqpFmNkc1+dHTytda0+g9AZoucTAkB59IiUb8oyCoOjXEo0pBwwUsKxw1iT6Wgx6zITeefa7gxzIxrQDIhGedbT6KyXiheJHvI6RJCgDUrRcPTlxulhAkEAjHzGzkMmzFM02WqUidyv3TQzCBaoSBeWr+69j6PeLg/i+3szERleWXiHtgPb/s+DzY0P+rZYkILHuxNRiKQU2A==");String publicKey = keyMap.get("publicKey");String privateKey = keyMap.get("privateKey");System.out.println("公钥:"+publicKey);System.out.println("私钥:"+privateKey);// 原始字符串String message = "我是测试原始内容";System.out.println("原始数据:"+message);String messageEn = publicKeyEncrypt(message, publicKey);System.out.println("公钥加密后内容:" + messageEn);String messageDe = privateKeyDecrypt(messageEn, privateKey);System.out.println("私钥解密后内容:" + messageDe);System.out.println("=====================");//私钥加密,公钥解密String s = privateKeyEncrypt(message, privateKey);System.out.println("私钥加密后内容:"+s);String s1 = publicKeyDecrypt(s, publicKey);System.out.println("公钥解密后内容:"+s1);}/*** 随机生成密钥对** @throws NoSuchAlgorithmException*/public static Map<String, String> genKeyPair() throws NoSuchAlgorithmException {// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");// 初始化密钥对生成器,密钥大小为96-1024位keyPairGen.initialize(1024, new SecureRandom());// 生成一个密钥对,保存在keyPair中KeyPair keyPair = keyPairGen.generateKeyPair();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));// 得到私钥字符串String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));// 将公钥和私钥保存到MapMap<String, String> map = new HashMap<>();map.put("publicKey", publicKeyString);map.put("privateKey", privateKeyString);return map;}/*** RSA公钥加密** @param str       加密字符串* @param publicKey 公钥* @return 密文* @throws Exception 加密过程中的异常信息*/public static String publicKeyEncrypt(String str, String publicKey) throws Exception {//base64编码的公钥byte[] decoded = Base64.decodeBase64(publicKey);RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));//RSA加密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, pubKey);String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));return outStr;}/*** RSA私钥解密** @param str        加密字符串* @param privateKey 私钥* @return 铭文* @throws Exception 解密过程中的异常信息*/public static String privateKeyDecrypt(String str, String privateKey) throws Exception {//64位解码加密后的字符串byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));//base64编码的私钥byte[] decoded = Base64.decodeBase64(privateKey);RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));//RSA解密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, priKey);String outStr = new String(cipher.doFinal(inputByte));return outStr;}/*** RSA私钥加密** @param str* @param privateKey* @return* @throws Exception*/public static String privateKeyEncrypt(String str, String privateKey) throws Exception {//base64编码的公钥byte[] decoded = Base64.decodeBase64(privateKey);PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));//RSA加密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, priKey);String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes()));return outStr;}/*** RSA公钥解密** @param str* @param publicKey* @return* @throws Exception*/public static String publicKeyDecrypt(String str, String publicKey) throws Exception {//64位解码加密后的字符串byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));//base64编码的私钥byte[] decoded = Base64.decodeBase64(publicKey);PublicKey pubKey =  KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));//RSA解密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, pubKey);String outStr = new String(cipher.doFinal(inputByte));return outStr;}
}

传入公钥私钥,进行解密,执行testAll方法,解密结果为:
在这里插入图片描述

源码地址

公钥私钥源码github


http://www.ppmy.cn/news/10107.html

相关文章

JEECGboot数据规则篇

使用 一、功能说明 列表数据权限&#xff0c;主要通过数据权限控制行数据&#xff0c;让不同的人有不同的查看数据规则&#xff1b; 比如&#xff1a; 销售人员只能看自己的数据&#xff1b;销售经理可以看所有下级销售人员的数据&#xff1b;财务只看金额大于5000的数据等等…

flex布局

flex布局 以下6个属性设置在容器上 flex-direction &#xff1a;主轴的方向 flex-wrap &#xff1a;一条轴线排不下&#xff0c;如何换行 flex-flow justify-content &#xff1a;项目在主轴上的对齐方式&#xff08;水平轴&#xff09; align-items &#xff1a;项目在交叉轴上…

数据在内存中存储☞(超详解)

目录 一.数据类型大家族 1.了解类型的意义 2.数据类型大家族的分类 二.详解☞数据储存之整形 1.储存方式 &#xff08;1&#xff09;.原码反码补码的概念 &#xff08;2&#xff09;.原码反码补码出现的原因&#xff1a; 计算机中只有加法器没有减法器&#xff0c;所有只…

python数据分析:采集分析岗位数据,看看薪资的高低都受什么因素影响呢

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ 在我们学习的时候,通常会产生疑问:这个行业前景好不好呢? 今天我们就用python的数据分析这个就业方向来举例 看一下都有哪些因素影响了薪资的高低呢&#xff1f; 数据采集 模块使用: reques…

VMware Workstation安装ESXI8.0

&#x1f388; 作者&#xff1a;互联网-小啊宇 &#x1f388; 简介&#xff1a; CSDN 运维领域创作者、阿里云专家博主。目前从事 Kubernetes运维相关工作&#xff0c;擅长Linux系统运维、开源监控软件维护、Kubernetes容器技术、CI/CD持续集成、自动化运维、开源软件部署维护…

php学习笔记-php运算符,类型转换,打印输出语句相较于其他语言的特殊部分-day02

php运算符&#xff0c;类型转换&#xff0c;打印输出语句相较于其他语言的特殊部分php运算符php的类型转换php打印输出语句php运算符 1.php运算符与其他高级语言相同的部分 算术运算符&#xff08;&#xff0c;-&#xff0c;*&#xff0c;/&#xff0c;%&#xff09;&#xff0…

进程间的8种通信方式

进程之间的通信方式有&#xff1a; 无名管道( pipe )、高级管道&#xff08;popen&#xff09;、有名管道&#xff08;named pipe&#xff09;、消息队列( message queue )、信号量( semophore ) 、信号 ( sinal ) 、共享内存( shared memory ) 、套接字( socket )。 1、无名管…

网络爬虫的危害与防御方法

爬虫程序是一种计算机程序&#xff0c;旨在通过执行自动化或重复性任务来模仿或替代人类的操作。爬虫程序执行任务的速度和准确性比真实用户高得多。爬虫程序在互联网上扮演着各种各样的角色&#xff0c;超过一半的网络流量是由爬虫程序产生的。有些爬虫程序非常有用&#xff0…