security部分添加注释

This commit is contained in:
ghy committed 2021-03-07 20:17:19 +08:00
1 parent 879e09e879
commit 9d370a5353
12 files changed
+396 -141

No files matched your search

@@ -3,12 +3,19 @@ package minsecurity.certificate.cert;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import minsecurity.Common;
import minsecurity.crypto.PublicKeyInterface;
import minsecurity.crypto.PublicKeyUtils;
import minsecurity.crypto.*;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.slf4j.LoggerFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Base64;
/*
* @Author: hongyu guo
@@ -21,6 +28,13 @@ public class CertUtils {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CertUtils.class);
public static final int VERSION1 = 1;
/**
* Certificate -> InnerCertificate
* @param certificate
* @return InnerCertificate
* @author hongyu guo
* @date 2021/3/7
**/
public static InnerCertificate parseCertToInnerCert(Certificate certificate){
TbsCertificate tbsCertificate = new TbsCertificate();
tbsCertificate.setVersion(certificate.getVersion());
@@ -43,6 +57,14 @@ public class CertUtils {
return innerCertificate;
}
/**
* InnerCertificate -> Certificate
* @param i
* @return minsecurity.certificate.cert.Certificate
* @author hongyu guo
* @date 2021/3/7
**/
public static Certificate parseInnerCertToCert(InnerCertificate i){
Certificate certificate = new Certificate();
@@ -64,6 +86,13 @@ public class CertUtils {
return certificate;
}
/**
* 检查证书是否在有效期内
* @param innerCertificate
* @return boolean
* @author hongyu guo
* @date 2021/3/7
**/
public static boolean checkDuration(InnerCertificate innerCertificate){
long curTime = System.currentTimeMillis();
// logger.debug("current time: {}", curTime);
@@ -74,26 +103,32 @@ public class CertUtils {
return true;
}
// cur = 1615018693993
// notbefore = 1615018693858
// notafter = 1615018694058
/**
* 使用publicKey验证签名
* @param cert
* @param publicKey
* @return boolean
* @author hongyu guo
* @date 2021/3/7
**/
public static boolean checkSign(InnerCertificate cert, PublicKeyInterface publicKey) throws Exception {
switch (cert.getTbsCertificate().getSignatureAlgorithm()){
case Common.SM3withSM2:
// TODO: 证书序列化方法
byte[] bytesOfCert = serialization(cert.getTbsCertificate());
logger.debug("验签序列化bytes: {}", ByteUtils.toHexString(bytesOfCert));
// byte[] digest = HashAlgo.sm3(bytesOfCert);
logger.debug("验签sign: {}", ByteUtils.toHexString(cert.getSignatureValue()));
return publicKey.verify(bytesOfCert, cert.getSignatureValue());
default:
throw new Exception("未定义的签名方法");
}
}
// TODO: 证书序列化方法
/**
* 将TbsCertificate类型实例转化为字节流
* @param tbsCertificate
* @return byte[]
* @author hongyu guo
* @date 2021/3/7
**/
public static byte[] serialization(TbsCertificate tbsCertificate){
ObjectMapper mapper = new ObjectMapper();
byte[] bytesOfCertJson;
@@ -106,6 +141,13 @@ public class CertUtils {
return new byte[0];
}
/**
* 将InnerCertificate类型实例转化为字节流
* @param innerCertificate
* @return byte[]
* @author hongyu guo
* @date 2021/3/7
**/
public static byte[] serialization(InnerCertificate innerCertificate){
ObjectMapper mapper = new ObjectMapper();
byte[] bytesOfCertJson;
@@ -118,17 +160,23 @@ public class CertUtils {
return new byte[0];
}
// TODO: 证书反序列化
/**
* 根据typeOfCert可将字节流反序列化为TbsCertificate或InnerCertificate,
* 返回Object类型, 调用者调用时需要手动强制类型转化
* @param bytesOfCert 字节流
* @param typeOfCert Common.TbsCertificate或Common.InnerCertificate
* @return java.lang.Object
* @author hongyu guo
* @date 2021/3/7
**/
public static Object deserialization(byte[] bytesOfCert, int typeOfCert){
ObjectMapper mapper = new ObjectMapper();
try {
switch (typeOfCert) {
case Common.TbsCertificate:
TbsCertificate tbsCertificate = mapper.readValue(bytesOfCert, TbsCertificate.class);
return tbsCertificate;
return mapper.readValue(bytesOfCert, TbsCertificate.class);
case Common.InnerCertificate:
InnerCertificate innerCertificate = mapper.readValue(bytesOfCert, InnerCertificate.class);
return innerCertificate;
return mapper.readValue(bytesOfCert, InnerCertificate.class);
default:
throw new CertException("未知证书类型");
}
@@ -139,4 +187,134 @@ public class CertUtils {
}
/**
* 使用priv私钥给Certificate类型实例签名
* @param certificate 未签名证书
* @param priv 私钥
* @return void
* @author hongyu guo
* @date 2021/3/7
**/
public static void signCert(Certificate certificate, PrivateKeyInterface priv) throws Exception {
byte[] bytesOfCert = serialization(CertUtils.parseCertToInnerCert(certificate).getTbsCertificate());
// logger.debug("签名序列化bytes: {}", ByteUtils.toHexString(bytesOfCert));
switch (certificate.getSignatureAlgorithm()){
case Common.SM3withSM2:
certificate.setSignature(priv.sign(bytesOfCert));
break;
default:
logger.debug("signAlgo: {}", certificate.getSignatureAlgorithm());
throw new Exception("未定义的签名方法");
}
}
/**
* 使用ca的公钥对sub进行验签, 如果时根证书验签, 调用时ca与sub指向同一个实例
* @param ca
* @param sub
* @return boolean
* @author hongyu guo
* @date 2021/3/7
**/
public static boolean verifyCert(Certificate ca, Certificate sub) throws Exception {
InnerCertificate innerCertificate = CertUtils.parseCertToInnerCert(sub);
switch (innerCertificate.getTbsCertificate().getVersion()){
case CertUtils.VERSION1:
boolean isValid = CertUtils.checkDuration(innerCertificate);
// logger.debug("有效期内:{}", isValid);
if(!isValid)
return false;
if(sub.isCA()){ // 根证书, 自验证
return checkSign(innerCertificate, sub.getPublicKey());
} else { // 使用ca验证sub
return checkSign(innerCertificate, ca.getPublicKey());
}
default:
return false;
}
}
/**
* 证书序列化为String类型, 密码为null或为空时不对证书进行加密保存
* @param certificate
* @param passwd
* @param symAlgoMode Common.SM4CBC / Common.SM4ECB
* @return java.lang.String
* @author hongyu guo
* @date 2021/3/7
**/
public static String toPem(Certificate certificate, byte[] passwd, int symAlgoMode) throws CertException, NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidKeyException {
if(certificate.getSignature() == null){
throw new CertException("该证书未签名");
}
byte[] bytesOfCert = serialization(CertUtils.parseCertToInnerCert(certificate));
byte[] ret;
if(passwd != null && passwd.length > 0){
byte[] hashPasswd = HashAlgo.sm3(passwd);
if( hashPasswd.length == 32){
for(int i = 0; i < 16; i++){
hashPasswd[i] += hashPasswd[i + 16];
}
}
byte[] sm4Key = new byte[16];
System.arraycopy(hashPasswd,0,sm4Key,0,16);
switch (symAlgoMode){
case Common.SM4CBC:{
// TODO: PADDING??? IV?????
ret = Sm4.encrypt_CBC_Padding(sm4Key, new byte[16],bytesOfCert);
break;
}
case Common.SM4ECB:{
ret = Sm4.encrypt_ECB_Padding(sm4Key, bytesOfCert);
break;
}
default:
throw new CertException("未定义的对称加密算法");
}
} else {
ret = bytesOfCert;
}
return Base64.getEncoder().encodeToString(ret);
}
/**
* String类型证书转化为Certificate对象
* @param pemString
* @param passwd
* @param symAlgoMode Common.SM4CBC / Common.SM4ECB
* @return minsecurity.certificate.cert.Certificate
* @author hongyu guo
* @date 2021/3/7
**/
public static Certificate fromPem(String pemString, byte[] passwd, int symAlgoMode) throws CertException, BadPaddingException, NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchProviderException, InvalidKeyException {
if(pemString == null || pemString.equals("")){
throw new CertException("pem串为空");
}
byte[] bytesOfPem = Base64.getDecoder().decode(pemString);
byte[] bytesOfCert = new byte[0];
if(passwd != null && passwd.length > 0){
byte[] hashPasswd = HashAlgo.sm3(passwd);
if( hashPasswd.length == 32){
for(int i = 0; i < 16; i++){
hashPasswd[i] += hashPasswd[i + 16];
}
}
byte[] sm4Key = new byte[16];
System.arraycopy(hashPasswd,0,sm4Key,0,16);
switch (symAlgoMode){
case Common.SM4CBC:
bytesOfCert = Sm4.decrypt_CBC_Padding(sm4Key,new byte[16], bytesOfPem);
break;
case Common.SM4ECB:
bytesOfCert = Sm4.decrypt_ECB_Padding(sm4Key, bytesOfPem);
break;
}
} else {
bytesOfCert = bytesOfPem;
}
InnerCertificate innerCertificate = (InnerCertificate) deserialization(bytesOfCert, Common.InnerCertificate);
return CertUtils.parseInnerCertToCert(innerCertificate);
}
}