深入理解Java中的数字证书与密码学:详尽解析
最编程
2024-02-21 13:30:57
...
import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
public class CertCoder {
//证书类型x509
public static final String CERT_TYPE = "x.509";
/**
* 由keyStore获得私钥
* @param keyStorePath 密钥库路径
* @param alias 别名
* @param pwd 密码
* @return 私钥
* @throws Exception
*/
private static PrivateKey getPrivateKeyByKeyStore(String keyStorePath,String alias,String pwd) throws Exception {
//获取密钥库
KeyStore ks = getKeyStore(keyStorePath,pwd);
//获得私钥
return (PrivateKey)ks.getKey(alias,pwd.toCharArray());
}
/**
* 由证书获得公钥
* @param certPath 证书路径
* @return 公钥
* @throws Exception
*/
private static PublicKey getPublicKeyByKeyStore(String certPath) throws Exception {
//获得证书
Certificate certificate = getCertificate(certPath);
//获得公钥
return certificate.getPublicKey();
}
/**
* 获得证书
* @param certPath 证书路径
* @return 证书
*/
private static Certificate getCertificate(String certPath) throws Exception {
//实例化证书工厂
CertificateFactory factory = CertificateFactory.getInstance(CERT_TYPE);
//获取证书文件流
FileInputStream fis = new FileInputStream(certPath);
//生成证书
Certificate certificate = factory.generateCertificate(fis);
//关闭文件流
fis.close();
return certificate;
}
/**
* 获得证书
* @param keyStorePath 密钥库路径
* @param alias 别名
* @param password 密码
* @return 证书
* @throws Exception
*/
private static Certificate getCertificate(String keyStorePath,String alias,String password) throws Exception {
//获得密钥库
KeyStore keyStore = getKeyStore(keyStorePath,password);
//获得证书
return keyStore.getCertificate(alias);
}
/**
* 获取KeyStore
* @param keyStorePath 路径
* @param pwd 密码
* @return KeyStore
* @throws Exception
*/
private static KeyStore getKeyStore(String keyStorePath, String pwd) throws Exception {
//实例化密钥库
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
//获得密钥库文件流
FileInputStream is = new FileInputStream(keyStorePath);
//加载密钥库
keyStore.load(is,pwd.toCharArray());
//关闭文件流
is.close();
return keyStore;
}
/**
* 私钥加密
* @param data 待加密数据
* @param keyStorePath 密钥库路径
* @param alias 别名
* @param pwd 密码
* @return 加密数据
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data,String keyStorePath,String alias,String pwd) throws Exception {
//获取私钥
PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,pwd);
//对数据加密
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE,privateKey);
return cipher.doFinal(data);
}
/**
* 私钥解密
* @param data 待解密数据
* @param keyStorePath 密钥库路径
* @param alias 别名
* @param pwd 密码
* @return 解密后的数据
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data,String keyStorePath,String alias,String pwd) throws Exception {
//获取私钥
PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,pwd);
//解密操作
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE,privateKey);
return cipher.doFinal(data);
}
/**
* 公钥加密
* @param data 代加密数据
* @param certPath 证书路径
* @return 密文
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data,String certPath) throws Exception {
PublicKey publicKey = getPublicKeyByKeyStore(certPath);
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
return cipher.doFinal(data);
}
/**
* 公钥解密
* @param data 待解密数据
* @param cerPath 证书路径
* @return 明文
* @throws Exception
*/
public static byte[] decryptByOublicKey(byte[] data,String cerPath) throws Exception {
PublicKey publicKey = getPublicKeyByKeyStore(cerPath);
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE,publicKey);
return cipher.doFinal(data);
}
/**
* 由证书构建签名
* @param sign 待签名数据
* @param keyStorePath 密钥库路径
* @param alias 别名
* @param pwd 密码
* @return
* @throws Exception
*/
public static byte[] sign(byte[] sign,String keyStorePath,String alias,String pwd) throws Exception {
//获取证书
X509Certificate certificate = (X509Certificate) getCertificate(keyStorePath,alias,pwd);
//构建签名
Signature signature = Signature.getInstance(certificate.getSigAlgName());
//获取私钥
PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,pwd);
//初始化签名,有私钥构建
signature.initSign(privateKey);
signature.update(sign);
return signature.sign();
}
/**
* 认证
* @param data 数据
* @param sign 签名
* @param cerPath 证书路径
* @return 数据是否有改变
* @throws Exception
*/
public static boolean vertify(byte[] data,byte[] sign,String cerPath) throws Exception {
//获取证书
X509Certificate certificate = (X509Certificate) getCertificate(cerPath);
//获取公钥
PublicKey publicKey = certificate.getPublicKey();
Signature signature = Signature.getInstance(certificate.getSigAlgName());
signature.initVerify(publicKey);
signature.update(data);
return signature.verify(sign);
}
public static void main(String[] args) throws Exception {
String pwd = "Lu3jianL6";
String alias = "www.zlex.org";
String cerPath = "D:\\Program Files\\Java\\jdk1.8.0_201\\bin\\zlex.cer";
String keyStorePath = "D:\\Program Files\\Java\\jdk1.8.0_201\\bin\\zlex.keystore";
byte[] data = "心里有思念的人就不会孤独".getBytes("utf-8");
System.err.println("公钥加密,私钥解密");
byte[] bytes = encryptByPublicKey(data, cerPath);
System.out.println("公钥加密:" + new String(bytes,"utf-8"));
byte[] result = decryptByPrivateKey(bytes, keyStorePath, alias, pwd);
System.out.println("私钥解密:"+new String(result,"utf-8"));
System.err.println("私钥加密,公钥解密");
byte[] result1 = encryptByPrivateKey(data, keyStorePath, alias, pwd);
System.out.println("私钥加密:" + new String(result1,"utf-8"));
byte[] bytes1 = decryptByOublicKey(result1, cerPath);
System.out.println("公钥解密:" + new String(bytes1,"utf-8"));
System.err.println("数字签名");
byte[] sign = sign(data,keyStorePath,alias,pwd);
System.out.println("签名:" + new String(sign,"utf-8"));
System.out.println(vertify(data,sign,cerPath));
}
}
//执行结果
公钥加密,私钥解密
???H[:A??D`U???J?*??..7?S??D?v8??O????D?*????x? o? "H*#H??`T?v???\rf???a?H??*a?Av?c?0'?MN?PQ?O???1.VR?at:hV?zY?==?/?ī,???????`???$(?^?s 7/??2?'??5??Tu0??Js|9K*E%?A??C?ea?29 ?{?SM????^ ????????lf)???+???k??I?$?8?
私钥加密,公钥解密
私钥解密:心里有思念的人就不会孤独
私钥加密:u?)??? -l?x?n???EQ?N/??*????x?9?\w?i}ZZ??K??v?k???????$??j?z?h?/f`???8L?$<s#??<??8se?ы ē?*J???R??^??IZz{????A??2I4???%? P????????!?o??XjRBryMj?Z?X w& ?h???R?????WR???>>??.\G?q????a?A??$???# %????????v??L`)?????
公钥解密:心里有思念的人就不会孤独
数字签名
签名:^???<C??WqN:A[?WM?t??+?RP?X??7?_<???Z?R,?i8%qЬa??!?>G-6U??|??6?1r9|??hQ????h? z?5???O* H9??N
v?F2~s6I???DX??R^?@)A?NY/g?*??oQU?I@w=?? ??hDv? h-?????lO???#?O?3?`?c?P??X?u5TaO??Cz4??p?1???@6KS???5?!< y<?34?x$?R3n?G
true
推荐阅读
-
Java 类加载器的作用 - 简介:类加载器是 Java™ 中一个非常重要的概念。类加载器负责将 Java 类的字节码加载到 Java 虚拟机中。本文首先详细介绍了 Java 类加载器的基本概念,包括代理模型、加载类的具体过程和线程上下文类加载器等。然后介绍了如何开发自己的类加载器,最后介绍了类加载器在 Web 容器和 OSGi™ 中的应用。 类加载器是 Java 语言的一项创新,也是 Java 语言广受欢迎的重要原因之一。它允许将 Java 类动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 开始出现,最初是为了满足 Java Applets 的需求而开发的,Java Applets 需要从远程位置下载 Java 类文件并在浏览器中执行。现在,类加载器已广泛应用于网络容器和 OSGi。一般来说,Java 应用程序的开发人员不需要直接与类加载器交互;Java 虚拟机的默认行为足以应对大多数情况。但是,如果遇到需要与类加载器交互的情况,而您又不太了解类加载器的机制,就很容易花费大量时间调试异常,如 ClassNotFoundException 和 NoClassDefFoundError。本文将详细介绍 Java 的类加载器,帮助读者深入理解 Java 语言中的这一重要概念。下面先介绍一些基本概念。 类加载器的基本概念 顾名思义,类加载器用于将 Java 类加载到 Java 虚拟机中。一般来说,Java 虚拟机以如下方式使用 Java 类:Java 源程序(.java 文件)经 Java 编译器编译后转换为 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码并将其转换为 java.lang 实例。每个实例都用来表示一个 Java 类。通过该实例的 newInstance 方法创建该类的对象。实际情况可能更加复杂,例如,Java 字节代码可能是由工具动态生成或通过网络下载的。 基本上,所有类加载器都是 java.lang.ClassLoader 类的实例。下面将详细介绍这个 Java 类。 java.lang.ClassLoader 类简介 java.lang.ClassLoader 类的基本职责是根据给定类的名称为其查找或生成相应的字节码,然后根据这些字节码定义一个 Java 类,即 java.lang.Class 类的实例。除此之外,ClassLoader 还负责加载 Java 应用程序所需的资源,如图像文件和配置文件。不过,本文只讨论它加载类的功能。为了履行加载类的职责,ClassLoader 提供了许多方法,其中比较重要的方法如表 1 所示。下文将详细介绍这些方法。 表 1.与加载类相关的 ClassLoader 方法
-
深入理解『云原生』K8s中的hostNetwork与NetworkPolicy:理论解析与实践操作指南
-
玩转Kotlin性能测试:JMH入门指南一 - 测试基础" "深入理解JMH在Kotlin中的应用:基准测试实战解析" "轻松实践Kotlin基准测试:JMH工具详解与实例总结
-
深入理解:Unix域Socket协议在networking中的工作机制与详细解析
-
深入理解Java安全:解析CC7链在Java反序列化中的影响
-
理解Java中的匿名内部类:如何访问外部类的细节与深入剖析
-
深入理解Java中的数字证书与密码学:详尽解析
-
深入解析密码学中的经典现象:生日悖论与破解手段——详解生日攻击
-
深入理解sklearn中的XGBModel:特征重要性详解、plot_importance功能解析与实用操作指南
-
深入理解Rust中的字符串操作与相关技巧:从三个角度解析字符串处理