我们知道,摘要算法用来确保数据没有被篡改,非对称加密算法可以对数据进行加解密,签名算法可以确保数据完整性和抗否认性,把这些算法集合到一起,并搞一套完善的标准,这就是数字证书。

因此,数字证书就是集合了多种密码学算法,用于实现数据加解密、身份认证、签名等多种功能的一种安全标准。

数字证书可以防止中间人攻击,因为它采用链式签名认证,即通过根证书(Root CA)去签名下一级证书,这样层层签名,直到最终的用户证书。而Root CA证书内置于操作系统中,所以,任何经过CA认证的数字证书都可以对其本身进行校验,确保证书本身不是伪造的。

我们在上网时常用的HTTPS协议就是数字证书的应用。浏览器会自动验证证书的有效性:

查看方式(以谷歌浏览器为例):

要使用数字证书,首先需要创建证书。正常情况下,一个合法的数字证书需要经过CA签名,这需要认证域名并支付一定的费用。开发的时候,我们可以使用自签名的证书,这种证书可以正常开发调试,但不能对外作为服务使用,因为其他客户端并不认可未经CA签名的证书。

在Java程序中,数字证书存储在一种Java专用的key store文件中,JDK提供了一系列命令来创建和管理key store。我们用下面的命令创建一个key store,并设定口令123456:

keytool -storepass 123456 -genkeypair -keyalg RSA -keysize 1024 -sigalg SHA1withRSA -validity 3650 -alias mycert -keystore my.keystore -dname "CN=www.sample.com, OU=sample, O=sample, L=BJ, ST=BJ, C=CN"

几个主要的参数是:

keyalg:是产生公私钥对所用的算法,这里指定RSA加密算法;

keysize:定义密钥的长度;

sigalg:签名算法,指定SHA1withRSA签名算法,即用RSA签名,用SHA1哈希算法摘要。

validity:指定证书有效期3650天;

alias:指定证书在程序中引用的名称;

dname:最重要的CN=www.sample.com指定了Common Name,如果证书用在HTTPS中,这个名称必须与域名完全一致。

执行上述命令,JDK会在当前目录创建一个my.keystore文件,并存储创建成功的一个私钥和一个证书,它的别名是mycert。

有了key store存储的证书,我们就可以通过数字证书进行加解密和签名:

import javax.crypto.Cipher;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.X509Certificate;public class TestCert {public static void main(String[] args) throws Exception {byte[] message = "Hello, use X.509 cert!".getBytes("UTF-8");// 读取KeyStore:KeyStore ks = loadKeyStore("my.keystore", "123456");// 读取私钥:PrivateKey privateKey = (PrivateKey) ks.getKey("mycert", "123456".toCharArray());// 读取证书:X509Certificate certificate = (X509Certificate) ks.getCertificate("mycert");// 加密:byte[] encrypted = encrypt(certificate, message);System.out.println(String.format("encrypted: %x", new BigInteger(1, encrypted)));// 解密:byte[] decrypted = decrypt(privateKey, encrypted);System.out.println("decrypted: " + new String(decrypted, "UTF-8"));// 签名:byte[] sign = sign(privateKey, certificate, message);System.out.println(String.format("signature: %x", new BigInteger(1, sign)));// 验证签名:boolean verified = verify(certificate, message, sign);System.out.println("verify: " + verified);}static KeyStore loadKeyStore(String keyStoreFile, String password) {try (InputStream input = TestCert.class.getResourceAsStream(keyStoreFile)) {if (input == null) {throw new RuntimeException("file not found in classpath: " + keyStoreFile);}KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());ks.load(input, password.toCharArray());return ks;} catch (Exception e) {throw new RuntimeException(e);}}static byte[] encrypt(X509Certificate certificate, byte[] message) throws GeneralSecurityException {Cipher cipher = Cipher.getInstance(certificate.getPublicKey().getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, certificate.getPublicKey());return cipher.doFinal(message);}static byte[] decrypt(PrivateKey privateKey, byte[] data) throws GeneralSecurityException {Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}static byte[] sign(PrivateKey privateKey, X509Certificate certificate, byte[] message)throws GeneralSecurityException {Signature signature = Signature.getInstance(certificate.getSigAlgName());signature.initSign(privateKey);signature.update(message);return signature.sign();}static boolean verify(X509Certificate certificate, byte[] message, byte[] sig) throws GeneralSecurityException {Signature signature = Signature.getInstance(certificate.getSigAlgName());signature.initVerify(certificate);signature.update(message);return signature.verify(sig);}
}

在上述代码中,我们从key store直接读取了私钥-公钥对,私钥以PrivateKey实例表示,公钥以X509Certificate表示,实际上数字证书只包含公钥,因此,读取证书并不需要口令,只有读取私钥才需要。如果部署到Web服务器上,例如Nginx,需要把私钥导出为Private Key格式,把证书导出为X509Certificate格式。

以HTTPS协议为例,浏览器和服务器建立安全连接的步骤如下:

①浏览器向服务器发起请求,服务器向浏览器发送自己的数字证书;

②浏览器用操作系统内置的Root CA来验证服务器的证书是否有效,如果有效,就使用该证书加密一个随机的AES口令并发送给服务器;

③服务器用自己的私钥解密获得AES口令,并在后续通讯中使用AES加密。

上述流程只是一种最常见的单向验证。如果服务器还要验证客户端,那么客户端也需要把自己的证书发送给服务器验证,这种场景常见于网银等。

注意:数字证书存储的是公钥,以及相关的证书链和算法信息。私钥必须严格保密,如果数字证书对应的私钥泄漏,就会造成严重的安全威胁。如果CA证书的私钥泄漏,那么该CA证书签发的所有证书将不可信。数字证书服务商DigiNotar就发生过私钥泄漏导致公司破产的事故。

小结

数字证书就是集合了多种密码学算法,用于实现数据加解密、身份认证、签名等多种功能的一种安全标准。

数字证书采用链式签名管理,顶级的Root CA证书已内置在操作系统中。

数字证书存储的是公钥,可以安全公开,而私钥必须严格保密。

转载:https://www.liaoxuefeng.com/wiki/1252599548343744/1304227968188450

数字证书的创建与使用(采用java)相关推荐

  1. java usbkey数字证书_Java创建数字证书

    BouncyCastle下载: 链接:http://pan.baidu.com/s/1vrcL4    密码:6i27 package com.what21.security05; import ja ...

  2. 用java创建一个单例模式,采用Java实现单例模式

    一. 背景 单例模式是指在内存中只会创建且仅创建一次对象的设计模式.在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用 ...

  3. 项目中用到的数字证书的创建,签名实现

    首先 需要下载jar包 bcprov-jdk15-145.jar 实体类 package com.hongan.lh.cert; import java.security.KeyPair; impor ...

  4. 天威诚信-数字证书认证系统iTrusCA

    iTrusCA数字证书认证系统 refurl: http://www.itrus.com.cn/2014/0915/1091.html 1.产品简介 天威诚信数字证书认证系统(下文简称"iT ...

  5. 数字证书 - Java加密与安全

    数字证书我们在前面看到了一些计算机密码学的一些算法1. 摘要算法确保数据没有被篡改2. 非对称加密就是对数据进行加解密3. 数据签名可以确保数据完整性和抗否认性而数字证书就是集合了多种密码学算法,用于 ...

  6. java产生的数字发送到页面_JAVA中数字证书的维护及生成方法

    Java中的keytool.exe可以用来创建数字证书,所有的数字证书是以一条一条(采用别名区别)的形式存入证书库的中,证书库中的一条证书包含该条证书的私钥,公钥和对应的数字证书的信息.证书库中的一条 ...

  7. 数字证书及其简单数字签名的实现(java实现)

    <!--[if !supportLists]-->1.<!--[endif]-->引导语/数字证书的应用 提到数字证书,大家首先可能想到这些.  然而其实这些也是数字证书运用很 ...

  8. 1、【java数据安全】数据安全之加密解密(base64、MD、SHA、DES、AES、IDEA、PBE、DH、RSA、EIGamal)、数字签名(DSA、ECDSA)和数字证书介绍、应用示例详细介绍

    java数据安全 系列文章 1.[java数据安全]数据安全之加密解密(base64.MD.SHA.DES.AES.IDEA.PBE.DH.RSA.EIGamal).数字签名(DSA.ECDSA)和数 ...

  9. java生成数字证书_java生成数字证书方法

    Java 中生成数字证书也很简单的. 1.创建证书 Java 中的 keytool.exe (位于 JDKBin 目录下)可以用来创建数字证书,所有的数字证书是以一条一条(采用别名区别)的形式存入证书 ...

最新文章

  1. 使用Silverlight Toolkit TreeView(树形控件)
  2. python四大高阶函数_详谈Python高阶函数与函数装饰器(推荐)
  3. SOFAStack的前世今生
  4. Python实现单例
  5. matlab 编辑器设置,编辑器设置,包括语言、备份和显示设置
  6. Linux基础(3)--搭建最小的Linux系统
  7. 拳王虚拟项目公社:如何通过知识付费赚钱,知识付费搬运赚钱,虚拟资源付费项目
  8. snipaste安装和使用_snipaste替代品 amp; linux截图解决方案-截图、贴图工具Flameshot...
  9. 支付宝人脸识别身份证认证(新版SDK)
  10. 区块链组适应不断变化的监管环境
  11. 62个程序员崩溃的瞬间,你经历过了吗?哈哈哈哈哈嗝~
  12. web应用开发入门_Web应用程序监视入门
  13. 【golang】golang使用cmd去ping网址在window和linux的区别
  14. 利用Joypy绘制嵴线图的案例
  15. 【计算机网络】6 路由器与静态路由配置
  16. 黑马 React 学习记录
  17. Java基础面经汇总
  18. fastreport 打印有 demo version字样_噬神者3免费试玩DEMO试玩 | 伊迪丝芬奇的记忆将登陆SWITCH...
  19. STM32F407GPIO
  20. 编译原理 —— 属性文法和语义规则

热门文章

  1. 元宵节快乐,拜个晚年,说2个近期的活动
  2. 纯JavaScript二维码在线生成网页源码
  3. 转载内存授予(memory grants)的理解
  4. SQL Server计算一年中的第几周
  5. ps更换证件照的背景色
  6. 读书笔记:《钱穆-zg历代zz得失》
  7. Attention机制的精要总结,附:中英文机器翻译的实现!
  8. 深度对比:电子合同与纸质合同到底有哪些差异?
  9. 力扣算法题-19.秋叶收藏集 C语言实现
  10. mysql5.6只有解压缩_MySQL 5.6 for Windows 解压缩版配置安装