数字证书的相关专业名词(上)---PKI和PKCS

一、前言

最近确实比较忙,有一个SM2协同签名算法需要通过java实现,这个确实想了非常非常久,不过最近也差不多将这个项目初步解决了,等着后面的对接。项目顺利结束后,我会将在该项目中的所学分享出来,我觉得这个技术确实非常值得分享,因为从资料上确实很难找到,神奇的gpt虽然能提供思路但是并不符合给我的论文标准,所以我只能通过论文一行行翻成java代码写出,也得到了很多大佬的帮助。
后面有空也会继续ES的学习,然后近日除了上面的项目外,接了一个校验X509证书有效性的一个项目,这个项目有很多专业性的知识,比如OCSP和CRL,这个之前完全不知道,所以通过这篇文章分享一下我的所学。这篇文章更多的是概念,感兴趣的小伙伴可以了解一下。

二、PKI

  • PKI指的是公钥基础设施(Public Key Infrastructure),是一种基于非对称加密技术和数字证书管理系统的安全框架。在PKI中,用户使用一对密钥:一个私钥和一个公钥。私钥只有用户自己知道,公钥则可以公开共享。
  • PKI通过数字证书来验证用户身份和保护数据传输的安全性。数字证书由认证机构(CA)签发,其中包含了用户的公钥、用户信息和CA的数字签名等元素。在进行网络通信时,接收方可以使用发送方的公钥来加密数据,并使用发送方的数字证书来验证其身份。这样,即使数据被窃取,黑客也无法破解加密信息,因为他们没有私钥。
  • PKI广泛应用于安全协议,如SSL/TLS、IPSec和S/MIME等。它提供了一种可靠、安全且可扩展的解决方案,以确保网络通信的保密性和完整性。
  • 其中关于PKI,比较重要的内容有数字证书,证书颁发机构(CA),数字签名,SSL/TLS协议。我们这儿主要讲一下数字证书,其他的大家可以自行查阅资料学习,我之前有讲过密码学相关基础知识的文章,其中涉及到了数字签名部分知识。

我们如果对相关领域进行过一点学习的人,都应该对下面的java中的几个类非常熟悉,其实它们都和PKI有关:

java.security.KeyPair:表示公钥和私钥对,可用于加密和解密数据。

java.security.PublicKey:表示公钥,可用于验证数字签名或加密数据。

java.security.PrivateKey:表示私钥,可用于创建数字签名或解密数据。

java.security.cert.Certificate:表示数字证书,包括X509证书。

java.security.cert.X509Certificate:表示X509数字证书,常用于SSL / TLS安全协议中。

javax.net.ssl.SSLContext:提供安全套接字协议(SSL / TLS)的访问点。

javax.net.ssl.KeyManagerFactory:用于管理密钥的工厂类。

javax.net.ssl.TrustManagerFactory:用于管理信任的工厂类。

javax.crypto.Cipher:提供加密和解密功能的类。

javax.crypto.KeyGenerator:提供密钥生成器的类。这里是引用

这些类提供了处理PKI相关任务所需的基本API。使用这些类和API,开发人员可以构建安全的应用程序和服务,以确保网络通信的机密性、完整性和身份验证。

2.1、什么是数字证书

  • 数字证书是公钥基础设施(PKI)中用于验证身份的一种数字凭证。它包含了一个用户或实体的信息,以及该实体与其公钥之间的数字签名。数字证书通常由第三方认证机构(CA)颁发,以确保其真实性和可信度
  • 数字证书中包含的信息通常包括证书持有人的名称、公钥、有效期、证书颁发机构的名称和数字签名等元素数字证书可以用于加密通讯、数字签名、身份验证等应用。例如,在浏览器中,数字证书被用于建立HTTPS连接,以确保安全的数据传输。
  • 数字证书通过公钥加密技术来实现,数字签名可以确保证书信息的完整性和真实性。当客户端接收到数字证书时,它会检查数字签名以确认证书是否由受信任的CA签发,并使用其中的公钥来验证签名。如果数字签名有效,则可以信任该证书,从而建立安全的通信连接。
    数字证书的相关专业名词(上)---PKI和PKCS_第1张图片
  • 数字证书的核心原理是公钥基础设施(PKI)。在PKI中,证书颁发机构(CA)负责颁发数字证书并维护证书撤销列表(CRL)。当用户与服务器进行连接时,客户端会从服务器获取数字证书并验证其有效性,以确保与服务器连接的安全性。

2.2、PKCS

PKCS是公钥密码学标准(Public-Key Cryptography Standards)的缩写,是由RSA安全公司和其他一些安全公司共同发布的一系列密码学标准。
PKCS包括许多不同的标准,其中一些最常见的是:

PKCS#1:定义了RSA加密算法、数字签名算法以及散列函数等。
PKCS#7:定义了加密消息语法(CMS),用于在网络上传输被加密过的数据。
PKCS#8:定义了私钥信息语法标准,用于在网络上传输私钥。
PKCS#9:定义了扩展证书属性以及基于PKI应用的相关信息。
PKCS#10:定义了证书请求语法标准,用于向证书颁发机构(CA)请求数字证书。
PKCS#11:定义了加密设备API标准,允许应用程序与安全令牌、智能卡等加密设备进行交互。
PKCS#12:定义了个人信息交换语法标准,用于在不同平台之间交换个人身份信息、私钥和证书等。

可能大家比较熟悉的是p1,p7,p10,p12

2.2.1、PKCS#1

  • PKCS#1是一种公钥密码学标准,定义了RSA加密算法、数字签名算法以及散列函数等
  • 它最初于1991年发布,随后经历了许多版本的更新和改进。其中,PKCS#1 v2.0是一个重要的版本,它引入了更安全的RSA算法,并将RSA数字签名算法与散列函数进行了结合,以便提供更好的安全性和可靠性。
  • PKCS#1中定义了使用RSA算法进行加密和解密的格式、填充方案和参数设置。它还定义了使用RSA算法进行数字签名和验证的格式、填充方案和参数设置。
  • 在使用RSA进行加密时,PKCS#1规定了使用随机填充方案,以防止攻击者通过对明文和加密结果之间的关系进行分析来破解加密算法。此外,PKCS#1还规定了加密数据的格式,以确保接收方能够正确地解密数据。
  • 在使用RSA进行数字签名时,PKCS#1规定了使用RSA算法和散列函数进行数字签名,并指定了数字签名的格式。此外,PKCS#1还规定了如何进行数字签名验证,以确保数字签名的有效性。
  • 总之,PKCS#1为使用RSA算法提供了一个清晰的框架,并定义了通用的格式、填充方案和参数设置,使得不同供应商之间的实现可以更加互操作性。

2.2.2、PKCS#7

  • PKCS#7(Public Key Cryptography Standards#7)是一组密码学标准,用于数字签名、加密和证书管理。PKCS#7最初由RSA Security公司开发,现已成为国际标准。
  • PKCS#7定义了一种安全消息语法(CMS),它是一个通用的加密、签名和压缩消息的格式。CMS提供了一种可扩展的方式来创建数字签名和加密数据,并允许多个参与者在完成操作后向消息中添加内容。在实践中,PKCS#7主要用于数字签名和加密消息。数字签名可以确保消息的完整性和真实性,而加密则可以保护消息的机密性。
  • 总之,PKCS#7是一种广泛使用的密码学标准,用于加密、签名和管理安全消息。CMS作为其核心部分,是一种通用的消息格式,允许多个参与者在完成操作后向消息中添加内容。

在java中,我们一般比较熟悉PdfPKCS7这个类
PdfPKCS7是iText库中的一个类,用于实现数字签名和加密PDF文件,该类提供了以下主要方法:

getEncodedPKCS7(byte[] hash, PdfSigner.CryptoStandard subfilter, Certificate[] chain, OcspClient ocspClient, CrlClient crlClient, TSAClient tsaClient)  //使用指定的哈希值对PDF文档进行数字签名,并返回签名结果的DER编码格式。
getAuthenticatedAttributeBytes(byte[] hash, PdfSigner.CryptoStandard subfilter, byte[] ocsp, byte[] crlBytes, long signingTime)  //获取经过身份验证的属性数据。
getTimestampToken(byte[] imprint)  //使用时间戳机构向签名添加时间戳。

其中,getEncodedPKCS7() 方法接受待签名数据的哈希值、签名类型、证书链、OCSP客户端、CRL客户端以及TSA客户端等参数,使用私钥对哈希值进行签名,并返回签名结果的DER编码格式。

getAuthenticatedAttributeBytes() 方法用于创建签名的身份验证属性。该方法接受待签名数据的哈希值、签名类型、OCSP响应、CRL字节数组、签名时间等参数,并返回经过身份验证的属性数据。

getTimestampToken() 方法用于在签名上添加时间戳。该方法接受待签名数据的哈希值,并返回经过时间戳机构签名的时间戳令牌。

PdfPKCS7类是iText库中实现数字签名的重要组成部分,它通过提供数字签名的核心算法和相关参数,实现了对PDF文档进行加密和签名的功能。

2.2.3、PKCS#10

  • PKCS#10是公钥证书请求语法标准(Public-Key Certificate Request Syntax),也称为证书签名请求(CSR)。它定义了一种格式,用于向证书颁发机构(CA)请求数字证书,我们一般简称为P10。
  • PKCS#10规范定义了一种通用的证书请求格式,其中包含有关证书请求者身份和所需证书类型的信息。该格式还指定了证书请求的签名算法,并将证书请求者的公钥嵌入到该请求中。
  • 在使用PKCS#10生成证书请求时,首先需要生成一个密钥对,包括公钥和私钥。然后,将证书请求发送给证书颁发机构,我们这个时候会通过密钥对的私钥对证书请求进行签名,以证明证书请求确实来自于该请求者。在这个过程中,私钥只保留在您的本地计算机上,并且不会被传输到证书颁发机构。因此,在 PKCS#10 中并不包含私钥
  • PKCS#10广泛用于创建X.509数字证书请求,这些证书请求可用于Internet上的SSL / TLS和VPN连接等应用程序中。
    我们拿网上生成SM2的PKCS#10请求为例,下面的例子创建了一个SM2withSM3算法的P10请求:

在java中,我们一般可以分为以下几步:

1.选择秘钥对的生成厂商,比如代码的第一行我们选择BC作为初始化密钥⼯⼚
2.生成密钥对,包括公钥,私钥
3.生成Dn,它主要包含客户信息,在java中的体现主要是下面的X500Name的构造过程
4.通过公钥,Dn生成证书请求CSR
5、用私钥对证书请求CSR进行签名,确保证书请求确实来自本人
6、构造P10

public static void main(String[] args) throws Exception {

        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        KeyPairGenerator localKeyPairGenerator = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());

        localKeyPairGenerator.initialize(256);

        KeyPair localKeyPair = localKeyPairGenerator.genKeyPair();

        X500NameBuilder localX500NameBuilder = new X500NameBuilder(BCStyle.INSTANCE);

        localX500NameBuilder.addRDN(BCStyle.CN, "39dian test");

        localX500NameBuilder.addRDN(BCStyle.C, "CN");

        localX500NameBuilder.addRDN(BCStyle.O, "39dian blog");

        localX500NameBuilder.addRDN(BCStyle.L, "shanghai");

        localX500NameBuilder.addRDN(BCStyle.ST, "shanghai");

        localX500NameBuilder.addRDN(BCStyle.EmailAddress, "[email protected]");

        X500Name localX500Name = localX500NameBuilder.build();

        JcaPKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(localX500Name, localKeyPair.getPublic());

        JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SM3WITHSM2");// 签名算法

        ContentSigner signer = csBuilder.build(localKeyPair.getPrivate());

        PKCS10CertificationRequest csr = p10Builder.build(signer);// PKCS10的请求

        System.out.println(Base64.encodeBase64String(csr.getEncoded()));

}

2.2.4、PKCS#12

  • PKCS#12是一种密码学标准,用于将公钥、私钥和证书等安全元素存储在单个文件中,以便于传输和备份。该标准最初由RSA Security公司开发,现已成为国际标准(RFC 7292)。
  • PKCS#12文件通常具有.pfx或.p12扩展名,我们比较熟悉的就是pfx,并可包含多个证书链和密钥对。这些文件可以使用口令进行加密,从而保护其中的敏感信息。使用PKCS#12文件时,需要提供正确的口令才能访问其中的私钥和证书。
  • PKCS#12文件广泛用于HTTPS协议中的服务器认证和客户端认证、VPN连接以及数字签名等安全应用领域。

然而,在传输过程中,如果未对PKCS#12文件进行适当的保护,文件内容可能会被截获并且可能会被恶意方访问到其中的私钥等敏感信息。因此,在传输PKCS#12文件之前需要采取一系列措施来确保它们的安全性,例如使用安全协议(如HTTPS)进行传输、使用加密算法对文件进行加密等等。
不过我们一般对于pfx文件,要么是内部进行传输,几乎不存在向外传输的可能,要么就只是做一个存储备份的功能,以防私钥等重要信息丢失。比如将pfx文件存进db,并且限制访问到这些数据的人员范围,以保证私钥和证书等敏感信息不会丢失。

你可能感兴趣的:(java,开发语言)