关于microservice:密码学系列之在线证书状态协议OCSP详解

简介咱们在进行网页拜访的时候会跟各种各样的证书打交道,比方在拜访https网页的时候,须要检测https网站的证书有效性。 OCSP就是一种校验协定,用于获取X.509数字证书的撤销状态。它是为了替换CRL而呈现的。 本文将会具体介绍OCSP的实现和长处。 PKI中的CRL咱们晓得在PKI架构中,CA证书是十分重要的组件,客户端通过CA证书来验证服务的可靠性。对于CA证书自身来说在创立的时候是能够指定过期工夫的。这样证书在过期之后就不能够应用,须要申请新的证书。 然而只给证书指定过期工夫是不够的,比方咱们因为业务的需要,须要撤销证书怎么办呢? PKI中提供了一个叫做CRL(certificate revocation list)的机制,用来维持被破除的证书列表。 这个CRL是由CA来颁发的,个别是在证书过期之前生成的。因为如果证书曾经过期了,那么这个CRL是无意义的。 对于CRL自身来说,它是一个证书列表,外面证书的格局通常也应用的是X.509。 CRL个别是由公布证书的CA来保护和公布的,公布CRL的组件叫做CRL issuer,通常来说CRL issuer和CA是同一个服务,然而你也能够依据须要将CRL issuer和CA进行拆分。 CRL是由CA定时来公布的,当然你也能够依照须要在须要撤销某个CA证书的时候从新公布CRL。所有的CRL都有过期工夫,在这个过期工夫之内,客户端能够依据CRL中的签名,去CA验证CRL的有效性,从而避免CRL的伪造。 CRL的毛病那么CRL有什么毛病呢? 首先CRL维持的是一个撤销的证书列表,为了保证系统的有效性,客户端在每次校验CA证书有效性的时候,都须要从CA服务器中获取这个CRL。而后通过CRL来校验对应的CA证书状态。 如果每次都去拿这个CRL,就有可能会有上面几个问题。 第一个问题是,如果CRL不可用,那么客户端就拿不到这个CRL,也就无奈校验CA证书的状态,从而造成服务不可用。 另外一个问题是,如果要撤销的证书比拟多的话,这个CRL可能会比拟大,从而造成网络资源的节约。 最初一个问题是PKI证书体系自身的目标是建设一个能够自我校验的,不依赖于在线服务的平安体系,如果每次都要在线获取CRL的话,就是去了PKI的这一劣势。 CRL的状态尽管CRL维持的是一个撤销证书列表,然而这个列表中证书的状态还是有所不同的。 CRL中证书的状态有两种,第一种就是证书曾经被撤销了,比方证书的颁发机构CA发现之前的颁布的证书是谬误的,或者因为其余的起因如私钥泄露导致原来的证书不够平安,须要将证书撤回。或者证书机构因为未恪守某些策略导致证书被撤消等,都须要将之前的证书设置为撤销状态。 还有一种状态是一个长期撤销的状态,这里叫做Hold状态,它示意证书临时是有效的,比方在用户没有确定私钥是否失落的状况下。当用户最终找回了私钥,则这个证书还是能够被复原的。 OCSP的工作流程既然CRL有这么多毛病,所以一个用来代替CRL的OCSP协定呈现了。 咱们先来看一下OCSP的工作流程。 如果A和B要进行应用PKI进行通信。为了保障通信的安全性,A将本人的公钥发给B,并通知B,这是我的公钥,你能够用这个公钥来校验我发送给你的音讯。 B在收到A的公钥之后,并不能确定A的公钥就是正确的,没有被篡改的。于是从A的公钥中提取出serial number,并将其封装到一个'OCSP request'中发给CA服务器。 CA服务器中的OCSP responder读取到了'OCSP request'申请,并从中提取出A的公钥的serial number。OCSP responder从CA服务器的数据库中查问这个serial number是否在这个数据库被撤销的列表中。 如果发现不在,那么意味着A的公钥依然是无效的,OCSP responder将会发送一个签名后的OCSP response给B。 B通过应用CA服务器的公钥验证OCSP response的有效性,从而确认A的公钥依然无效 。 最初B应用A的公钥和A进行通信。 OCSP的长处从下面的OCSP的工作流程咱们能够大略总结出上面几个OCSP绝对于CRL的长处。 首先OCSP响应的数据量要比CRL要小,所以对网络的要求和压力更少。 另外因为OCSP响应要解析的数据更少,所以OCSP客户端的实现要比CRL更加简略。 尽管因为CRL的各种毛病,在web环境中曾经不再被应用,而是被更加高效的OCSP替换,然而CRL依然被运行在CA的其余环境中。 OCSP协定的细节OCSP协定是在RFC 6960中定义的。 OCSP协定能够分为申请协定和响应协定两局部,接下来别离来进行介绍。 OCSP申请一个OCSP申请须要蕴含协定版本号,申请服务,要校验的证书identifier和可选的扩大局部。 OCSP responder在接管到OCSP的申请之后,会去校验OCSP音讯的有效性,如果音讯有问题则会返回异样,否则的话会依据申请的服务进行解决。 OCSP申请如果用ASN.1(Abstract Syntax Notation One)形象语法标记这能够如下示意: OCSPRequest ::= SEQUENCE { tbsRequest TBSRequest, optionalSignature [0] EXPLICIT Signature OPTIONAL } TBSRequest ::= SEQUENCE { version [0] EXPLICIT Version DEFAULT v1, requestorName [1] EXPLICIT GeneralName OPTIONAL, requestList SEQUENCE OF Request, requestExtensions [2] EXPLICIT Extensions OPTIONAL } Signature ::= SEQUENCE { signatureAlgorithm AlgorithmIdentifier, signature BIT STRING, certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL} Version ::= INTEGER { v1(0) } Request ::= SEQUENCE { reqCert CertID, singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } CertID ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, issuerNameHash OCTET STRING, -- Hash of issuer's DN issuerKeyHash OCTET STRING, -- Hash of issuer's public key serialNumber CertificateSerialNumber }ASN.1是一个接口描述语言,通过ASN.1,咱们能够很清晰的形容数据的格局信息。 ...

July 6, 2022 · 2 min · jiezi

关于microservice:密码学-09-AES

AES表一:算法秘钥长度秘钥长度默认值工作模式填充模式备注AES128,192,256128ECB,CBC,PCBC,CTR,CTS,CFB,CFB8至CFB128,OFB,OFB8至OFB128NoPadding,PKCS5Padding,ISO10126PaddingJava6实现若应用256位秘钥须要取得无政策限度权限文件(Unlimited Strength Jurisdiction Policy Files)AES同上同上同上PKCS7Padding,ZeroBytePaddingBouncy Castle实现表二:AES秘钥长度(比特)分组长度(比特)向量长度(比特)加密轮数AES-12812812812810AES-19219212812812AES-256256128128141 依据密钥长度不同,分为AES128、AES192、AES2561.特点ECB模式和CBC模式的区别对称加密算法里,应用NOPadding,加密的明文必须等于分组长度倍数,否则报错如果应用PKCS5Padding,会对加密的明文填充1字节-1个分组的长度没有指明加密模式和填充形式,示意应用默认的AES/ECB/PKCS5Padding加密后的字节数组能够编码成Hex、Base64AES算法明文按128位进行分组加密,能够调用cipher.getBlockSize()来获取要复现一个对称加密算法,须要失去明文、key、iv、mode、padding明文、key、iv须要留神解析形式,而且不肯定是字符串模式如果加密模式是ECB,则不须要加iv,加了的话会报错如果明文中有两个分组的内容雷同,ECB会失去齐全一样的密文,CBC不会加密算法的后果通常与明文等长或者更长,如果变短了,那可能是gzip、protobuf2.代码实现 public static String encryptAES(String plaintext) throws Exception { // 初始化秘钥 和加密算法 秘钥为16位 SecretKeySpec keySpec = new SecretKeySpec("0123456789abcdef".getBytes(StandardCharsets.UTF_8),"AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec("hengdinghengding".getBytes(StandardCharsets.UTF_8)); // 失去Cipher的实例 026fcbe02f76529d0a5bb3904aa6efdc C5sV2ktEoPUVHc/EwB811b8xuRnjiS3cO1khLWp7EeY= Cipher des = Cipher.getInstance("AES/CBC/PKCS5Padding"); // 对Cipher 实例进行初始化, des.init(Cipher.ENCRYPT_MODE,keySpec,ivParameterSpec); // update并不会每次都减少要加密的字符串的长度,并不牢靠。现实中的状态是 xiaojianbang +hengdi 解密发现只有banghengdi// des.update("xiaojianbang".getBytes(StandardCharsets.UTF_8)); // 加密 由字符串 失去的byte[] byte[] res=des.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); Log.d("hengdi","AES byte test" + Arrays.toString(res)); // 将 byte[] 实例化为 ByteString 对象 ByteString bty= ByteString.of(res); // hex 编码 String str_hex= bty.hex(); // base64 编码 String str_base64 = bty.base64(); return str_hex + " || " + str_base64; } public static String decryptAES(String cipherText) throws Exception { // 将加密后base64编码的字符串 解码,并还原成 byte[]// byte[] cipherTextBytes = ByteString.decodeHex(cipherText).toByteArray(); byte[] cipherTextBytes = ByteString.decodeBase64(cipherText).toByteArray(); SecretKeySpec keySpec = new SecretKeySpec("0123456789abcdef".getBytes(StandardCharsets.UTF_8),"AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec("hengdinghengding".getBytes(StandardCharsets.UTF_8)); // 失去Cipher的实例 026fcbe02f76529d0a5bb3904aa6efdc Am/L4C92Up0KW7OQSqbv3A== Cipher des = Cipher.getInstance("AES/CBC/PKCS5Padding"); des.init(Cipher.DECRYPT_MODE,keySpec,ivParameterSpec); byte[] res=des.doFinal(cipherTextBytes); return new String(res); }

December 25, 2021 · 1 min · jiezi