package cert import ( "b612.me/starlog" "crypto/dsa" "crypto/ecdh" "crypto/ecdsa" "crypto/ed25519" "crypto/rsa" "crypto/x509" "encoding/pem" "errors" "fmt" "os" "software.sslmate.com/src/go-pkcs12" "strings" ) func ParseCert(data []byte, pwd string) { { pems, err := pkcs12.ToPEM(data, pwd) if err == nil { for _, v := range pems { switch v.Type { case "CERTIFICATE": cert, err := x509.ParseCertificate(v.Bytes) if err != nil { continue } starlog.Green("这是一个PKCS12文件\n") starlog.Green("-----证书信息-----\n\n") starlog.Green("证书版本:%d\n", cert.Version) starlog.Green("证书序列号:%d\n", cert.SerialNumber) starlog.Green("证书签发者:%s\n", cert.Issuer) starlog.Green("证书开始时间:%s\n", cert.NotBefore) starlog.Green("证书结束时间:%s\n", cert.NotAfter) starlog.Green("证书扩展:%+v\n", cert.Extensions) starlog.Green("证书签名算法:%s\n", cert.SignatureAlgorithm) starlog.Green("证书签名:%x\n", cert.Signature) starlog.Green("证书公钥:%+v\n", cert.PublicKey) starlog.Green("证书公钥算法:%s\n", cert.PublicKeyAlgorithm) starlog.Green("证书密钥用法:%v\n", keyUsageToStrings(cert.KeyUsage)) starlog.Green("证书扩展密钥用法:%v\n", extKeyUsageToStrings(cert.ExtKeyUsage)) starlog.Green("证书是否CA:%t\n", cert.IsCA) starlog.Green("证书最大路径长度:%d\n", cert.MaxPathLen) starlog.Green("证书最大路径长度是否为0:%t\n", cert.MaxPathLenZero) starlog.Green("证书是否根证书:%t\n", cert.BasicConstraintsValid) starlog.Green("证书国家:%+v\n", cert.Subject.Country) starlog.Green("证书省份:%+v\n", cert.Subject.Province) starlog.Green("证书城市:%+v\n", cert.Subject.Locality) starlog.Green("证书组织:%+v\n", cert.Subject.Organization) starlog.Green("证书组织单位:%+v\n", cert.Subject.OrganizationalUnit) starlog.Green("证书通用名称:%s\n", cert.Subject.CommonName) starlog.Green("证书DNS:%+v\n", cert.DNSNames) starlog.Green("证书主题:%s\n", cert.Subject.String()) starlog.Green("-----公钥信息-----\n\n") pub := cert.PublicKey switch n := pub.(type) { case *rsa.PublicKey: starlog.Green("公钥算法为RSA\n") starlog.Green("公钥位数:%d\n", n.Size()) starlog.Green("公钥长度:%d\n", n.N.BitLen()) starlog.Green("公钥指数:%d\n", n.E) case *ecdsa.PublicKey: starlog.Green("公钥算法为ECDSA\n") starlog.Green("公钥位数:%d\n", n.Curve.Params().BitSize) starlog.Green("公钥曲线:%s\n", n.Curve.Params().Name) starlog.Green("公钥长度:%d\n", n.Params().BitSize) starlog.Green("公钥公钥X:%d\n", n.X) starlog.Green("公钥公钥Y:%d\n", n.Y) case *dsa.PublicKey: starlog.Green("公钥算法为DSA\n") starlog.Green("公钥公钥Y:%d\n", n.Y) case *ecdh.PublicKey: starlog.Green("公钥算法为ECDH\n") case *ed25519.PublicKey: starlog.Green("公钥算法为ED25519\n") default: starlog.Green("未知公钥类型\n") } case "PRIVATE KEY": priv, err := x509.ParsePKCS8PrivateKey(v.Bytes) if err != nil { priv, err = x509.ParsePKCS1PrivateKey(v.Bytes) if err != nil { priv, err = x509.ParseECPrivateKey(v.Bytes) if err != nil { starlog.Errorf("解析私钥错误:%s\n", err) continue } else { starlog.Green("这是一个ECDSA私钥\n") } } else { starlog.Green("这是一个PKCS1私钥\n") } } else { starlog.Green("这是一个PKCS8私钥\n") } starlog.Green("-----私钥信息-----\n\n") switch n := priv.(type) { case *rsa.PrivateKey: starlog.Green("这是一个RSA私钥\n") starlog.Green("私钥位数:%d\n", n.Size()) starlog.Green("私钥长度:%d\n", n.N.BitLen()) starlog.Green("私钥指数:%d\n", n.E) starlog.Green("私钥系数:%d\n", n.D) starlog.Green("私钥质数p:%d\n", n.Primes[0]) starlog.Green("私钥质数q:%d\n", n.Primes[1]) starlog.Green("私钥系数dP:%d\n", n.Precomputed.Dp) starlog.Green("私钥系数dQ:%d\n", n.Precomputed.Dq) starlog.Green("私钥系数qInv:%d\n", n.Precomputed.Qinv) case *ecdsa.PrivateKey: starlog.Green("这是一个ECDSA私钥\n") starlog.Green("私钥位数:%d\n", n.Curve.Params().BitSize) starlog.Green("私钥曲线:%s\n", n.Curve.Params().Name) starlog.Green("私钥长度:%d\n", n.Params().BitSize) starlog.Green("私钥系数:%d\n", n.D) starlog.Green("私钥公钥X:%d\n", n.PublicKey.X) starlog.Green("私钥公钥Y:%d\n", n.PublicKey.Y) case *dsa.PrivateKey: starlog.Green("这是一个DSA私钥\n") starlog.Green("私钥系数:%d\n", n.X) starlog.Green("私钥公钥Y:%d\n", n.Y) case *ed25519.PrivateKey: starlog.Green("这是一个ED25519私钥\n") case *ecdh.PrivateKey: starlog.Green("这是一个ECDH私钥\n") default: starlog.Green("未知私钥类型\n") } } } return } } idx := 0 for { idx++ block, rest := pem.Decode(data) if block == nil { if idx == 1 { starlog.Errorf("未知文件类型\n") } return } fmt.Println("\n--------------------------------\n") data = rest rt := 0 switch block.Type { case "CERTIFICATE": rt = 1 starlog.Green("这是一个证书文件\n") fallthrough case "CERTIFICATE REQUEST": if rt == 0 { starlog.Green("这是一个证书请求文件\n") } cert, err := x509.ParseCertificate(block.Bytes) if err != nil { starlog.Errorf("解析证书错误:%s\n", err) continue } starlog.Green("证书版本:%d\n", cert.Version) starlog.Green("证书序列号:%d\n", cert.SerialNumber) starlog.Green("证书签发者:%s\n", cert.Issuer) starlog.Green("证书开始时间:%s\n", cert.NotBefore) starlog.Green("证书结束时间:%s\n", cert.NotAfter) starlog.Green("证书扩展:%+v\n", cert.Extensions) starlog.Green("证书签名算法:%s\n", cert.SignatureAlgorithm) starlog.Green("证书签名:%x\n", cert.Signature) starlog.Green("证书公钥:%+v\n", cert.PublicKey) starlog.Green("证书公钥算法:%s\n", cert.PublicKeyAlgorithm) starlog.Green("证书密钥用法:%v\n", keyUsageToStrings(cert.KeyUsage)) starlog.Green("证书扩展密钥用法:%v\n", extKeyUsageToStrings(cert.ExtKeyUsage)) starlog.Green("证书是否CA:%t\n", cert.IsCA) starlog.Green("证书最大路径长度:%d\n", cert.MaxPathLen) starlog.Green("证书最大路径长度是否为0:%t\n", cert.MaxPathLenZero) starlog.Green("证书是否根证书:%t\n", cert.BasicConstraintsValid) starlog.Green("证书国家:%+v\n", cert.Subject.Country) starlog.Green("证书省份:%+v\n", cert.Subject.Province) starlog.Green("证书城市:%+v\n", cert.Subject.Locality) starlog.Green("证书组织:%+v\n", cert.Subject.Organization) starlog.Green("证书组织单位:%+v\n", cert.Subject.OrganizationalUnit) starlog.Green("证书通用名称:%s\n", cert.Subject.CommonName) starlog.Green("证书DNS:%+v\n", cert.DNSNames) starlog.Green("证书主题:%s\n", cert.Subject.String()) pub := cert.PublicKey switch n := pub.(type) { case *rsa.PublicKey: starlog.Green("公钥算法为RSA\n") starlog.Green("公钥位数:%d\n", n.Size()) starlog.Green("公钥长度:%d\n", n.N.BitLen()) starlog.Green("公钥指数:%d\n", n.E) case *ecdsa.PublicKey: starlog.Green("公钥算法为ECDSA\n") starlog.Green("公钥位数:%d\n", n.Curve.Params().BitSize) starlog.Green("公钥曲线:%s\n", n.Curve.Params().Name) starlog.Green("公钥长度:%d\n", n.Params().BitSize) starlog.Green("公钥公钥X:%d\n", n.X) starlog.Green("公钥公钥Y:%d\n", n.Y) case *dsa.PublicKey: starlog.Green("公钥算法为DSA\n") starlog.Green("公钥公钥Y:%d\n", n.Y) case *ecdh.PublicKey: starlog.Green("公钥算法为ECDH\n") case *ed25519.PublicKey: starlog.Green("公钥算法为ED25519\n") default: starlog.Green("未知公钥类型\n") } continue case "PRIVATE KEY": starlog.Infof("这是一个私钥文件\n") priv, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { priv, err = x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { priv, err = x509.ParseECPrivateKey(block.Bytes) if err != nil { starlog.Errorf("解析私钥错误:%s\n", err) continue } else { starlog.Green("这是一个ECDSA私钥\n") } } else { starlog.Green("这是一个PKCS1私钥\n") } } else { starlog.Green("这是一个PKCS8私钥\n") } switch n := priv.(type) { case *rsa.PrivateKey: starlog.Green("这是一个RSA私钥\n") starlog.Green("私钥位数:%d\n", n.Size()) starlog.Green("私钥长度:%d\n", n.N.BitLen()) starlog.Green("私钥指数:%d\n", n.E) starlog.Green("私钥系数:%d\n", n.D) starlog.Green("私钥质数p:%d\n", n.Primes[0]) starlog.Green("私钥质数q:%d\n", n.Primes[1]) starlog.Green("私钥系数dP:%d\n", n.Precomputed.Dp) starlog.Green("私钥系数dQ:%d\n", n.Precomputed.Dq) starlog.Green("私钥系数qInv:%d\n", n.Precomputed.Qinv) case *ecdsa.PrivateKey: starlog.Green("这是一个ECDSA私钥\n") starlog.Green("私钥位数:%d\n", n.Curve.Params().BitSize) starlog.Green("私钥曲线:%s\n", n.Curve.Params().Name) starlog.Green("私钥长度:%d\n", n.Params().BitSize) starlog.Green("私钥系数:%d\n", n.D) starlog.Green("私钥公钥X:%d\n", n.PublicKey.X) starlog.Green("私钥公钥Y:%d\n", n.PublicKey.Y) case *dsa.PrivateKey: starlog.Green("这是一个DSA私钥\n") starlog.Green("私钥系数:%d\n", n.X) starlog.Green("私钥公钥Y:%d\n", n.Y) case *ed25519.PrivateKey: starlog.Green("这是一个ED25519私钥\n") case *ecdh.PrivateKey: starlog.Green("这是一个ECDH私钥\n") default: starlog.Green("未知私钥类型\n") } continue case "PUBLIC KEY": starlog.Infof("这是一个公钥文件\n") pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { pub, err = x509.ParsePKCS1PublicKey(block.Bytes) starlog.Green("这是一个PKCS1公钥\n") } else { starlog.Green("这是一个PKIX公钥\n") } switch n := pub.(type) { case *rsa.PublicKey: starlog.Green("这是一个RSA公钥\n") starlog.Green("公钥位数:%d\n", n.Size()) starlog.Green("公钥长度:%d\n", n.N.BitLen()) starlog.Green("公钥指数:%d\n", n.E) case *ecdsa.PublicKey: starlog.Green("这是一个ECDSA公钥\n") starlog.Green("公钥位数:%d\n", n.Curve.Params().BitSize) starlog.Green("公钥曲线:%s\n", n.Curve.Params().Name) starlog.Green("公钥长度:%d\n", n.Params().BitSize) starlog.Green("公钥公钥X:%d\n", n.X) starlog.Green("公钥公钥Y:%d\n", n.Y) case *ecdh.PublicKey: starlog.Green("这是一个ECDH公钥\n") case *ed25519.PublicKey: starlog.Green("这是一个ED25519公钥\n") case *dsa.PublicKey: starlog.Green("这是一个DSA公钥\n") starlog.Green("公钥公钥Y:%d\n", n.Y) default: starlog.Green("未知公钥类型\n") } return default: starlog.Infof("未知证书文件类型\n") } } } func keyUsageToStrings(keyUsage x509.KeyUsage) string { var usages []string if keyUsage&x509.KeyUsageDigitalSignature != 0 { usages = append(usages, "Digital Signature") } if keyUsage&x509.KeyUsageContentCommitment != 0 { usages = append(usages, "Content Commitment") } if keyUsage&x509.KeyUsageKeyEncipherment != 0 { usages = append(usages, "Key Encipherment") } if keyUsage&x509.KeyUsageDataEncipherment != 0 { usages = append(usages, "Data Encipherment") } if keyUsage&x509.KeyUsageKeyAgreement != 0 { usages = append(usages, "Key Agreement") } if keyUsage&x509.KeyUsageCertSign != 0 { usages = append(usages, "Certificate Signing") } if keyUsage&x509.KeyUsageCRLSign != 0 { usages = append(usages, "CRL Signing") } if keyUsage&x509.KeyUsageEncipherOnly != 0 { usages = append(usages, "Encipher Only") } if keyUsage&x509.KeyUsageDecipherOnly != 0 { usages = append(usages, "Decipher Only") } return strings.Join(usages, ", ") } func extKeyUsageToStrings(extKeyUsages []x509.ExtKeyUsage) string { var usages []string for _, extKeyUsage := range extKeyUsages { switch extKeyUsage { case x509.ExtKeyUsageAny: usages = append(usages, "Any") case x509.ExtKeyUsageServerAuth: usages = append(usages, "Server Authentication") case x509.ExtKeyUsageClientAuth: usages = append(usages, "Client Authentication") case x509.ExtKeyUsageCodeSigning: usages = append(usages, "Code Signing") case x509.ExtKeyUsageEmailProtection: usages = append(usages, "Email Protection") case x509.ExtKeyUsageIPSECEndSystem: usages = append(usages, "IPSEC End System") case x509.ExtKeyUsageIPSECTunnel: usages = append(usages, "IPSEC Tunnel") case x509.ExtKeyUsageIPSECUser: usages = append(usages, "IPSEC User") case x509.ExtKeyUsageTimeStamping: usages = append(usages, "Time Stamping") case x509.ExtKeyUsageOCSPSigning: usages = append(usages, "OCSP Signing") case x509.ExtKeyUsageMicrosoftServerGatedCrypto: usages = append(usages, "Microsoft Server Gated Crypto") case x509.ExtKeyUsageNetscapeServerGatedCrypto: usages = append(usages, "Netscape Server Gated Crypto") default: usages = append(usages, fmt.Sprintf("Unknown(%d)", extKeyUsage)) } } return strings.Join(usages, ", ") } func GetCert(data []byte, pwd string) ([]any, []x509.Certificate, error) { var common []any var certs []x509.Certificate { pems, err := pkcs12.ToPEM(data, pwd) if err == nil { for _, v := range pems { switch v.Type { case "CERTIFICATE": cert, err := x509.ParseCertificate(v.Bytes) if err != nil { continue } starlog.Green("这是一个PKCS12文件\n") pub := cert.PublicKey switch pub.(type) { case *rsa.PublicKey: starlog.Green("公钥算法为RSA\n") case *ecdsa.PublicKey: starlog.Green("公钥算法为ECDSA\n") case *dsa.PublicKey: starlog.Green("公钥算法为DSA\n") case *ecdh.PublicKey: starlog.Green("公钥算法为ECDH\n") case *ed25519.PublicKey: starlog.Green("公钥算法为ED25519\n") default: starlog.Green("未知公钥类型\n") } common = append(common, pub) certs = append(certs, *cert) case "PRIVATE KEY": priv, err := x509.ParsePKCS8PrivateKey(v.Bytes) if err != nil { priv, err = x509.ParsePKCS1PrivateKey(v.Bytes) if err != nil { priv, err = x509.ParseECPrivateKey(v.Bytes) if err != nil { starlog.Errorf("解析私钥错误:%s\n", err) continue } else { starlog.Green("这是一个ECDSA私钥\n") } } else { starlog.Green("这是一个PKCS1私钥\n") } } else { starlog.Green("这是一个PKCS8私钥\n") } starlog.Green("-----私钥信息-----\n\n") switch n := priv.(type) { case *rsa.PrivateKey: starlog.Green("这是一个RSA私钥\n") starlog.Green("私钥位数:%d\n", n.Size()) case *ecdsa.PrivateKey: starlog.Green("这是一个ECDSA私钥\n") starlog.Green("私钥位数:%d\n", n.Curve.Params().BitSize) case *dsa.PrivateKey: starlog.Green("这是一个DSA私钥\n") case *ed25519.PrivateKey: starlog.Green("这是一个ED25519私钥\n") case *ecdh.PrivateKey: starlog.Green("这是一个ECDH私钥\n") default: starlog.Green("未知私钥类型\n") } common = append(common, priv) } } return common, certs, nil } } idx := 0 for { idx++ block, rest := pem.Decode(data) if block == nil { if idx == 1 { starlog.Errorf("未知文件类型\n") return common, certs, errors.New("未知文件类型") } return common, certs, nil } data = rest rt := 0 switch block.Type { case "CERTIFICATE": rt = 1 starlog.Green("这是一个证书文件\n") fallthrough case "CERTIFICATE REQUEST": if rt == 0 { starlog.Green("这是一个证书请求文件\n") } cert, err := x509.ParseCertificate(block.Bytes) if err != nil { starlog.Errorf("解析证书错误:%s\n", err) continue } common = append(common, cert.PublicKey) certs = append(certs, *cert) pub := cert.PublicKey switch pub.(type) { case *rsa.PublicKey: starlog.Green("公钥算法为RSA\n") case *ecdsa.PublicKey: starlog.Green("公钥算法为ECDSA\n") case *dsa.PublicKey: starlog.Green("公钥算法为DSA\n") case *ecdh.PublicKey: starlog.Green("公钥算法为ECDH\n") case *ed25519.PublicKey: starlog.Green("公钥算法为ED25519\n") default: starlog.Green("未知公钥类型\n") } continue case "PRIVATE KEY": starlog.Infof("这是一个私钥文件\n") priv, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { priv, err = x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { priv, err = x509.ParseECPrivateKey(block.Bytes) if err != nil { starlog.Errorf("解析私钥错误:%s\n", err) continue } else { starlog.Green("这是一个ECDSA私钥\n") } } else { starlog.Green("这是一个PKCS1私钥\n") } } else { starlog.Green("这是一个PKCS8私钥\n") } switch n := priv.(type) { case *rsa.PrivateKey: starlog.Green("这是一个RSA私钥\n") starlog.Green("私钥位数:%d\n", n.Size()) case *ecdsa.PrivateKey: starlog.Green("这是一个ECDSA私钥\n") starlog.Green("私钥位数:%d\n", n.Curve.Params().BitSize) case *dsa.PrivateKey: starlog.Green("这是一个DSA私钥\n") case *ed25519.PrivateKey: starlog.Green("这是一个ED25519私钥\n") case *ecdh.PrivateKey: starlog.Green("这是一个ECDH私钥\n") default: starlog.Green("未知私钥类型\n") } common = append(common, priv) continue case "PUBLIC KEY": starlog.Infof("这是一个公钥文件\n") pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { pub, err = x509.ParsePKCS1PublicKey(block.Bytes) starlog.Green("这是一个PKCS1公钥\n") } else { starlog.Green("这是一个PKIX公钥\n") } common = append(common, pub) switch n := pub.(type) { case *rsa.PublicKey: starlog.Green("这是一个RSA公钥\n") starlog.Green("公钥位数:%d\n", n.Size()) case *ecdsa.PublicKey: starlog.Green("这是一个ECDSA公钥\n") starlog.Green("公钥位数:%d\n", n.Curve.Params().BitSize) case *dsa.PublicKey: starlog.Green("这是一个DSA公钥\n") case *ecdh.PublicKey: starlog.Green("这是一个ECDH公钥\n") case *ed25519.PublicKey: starlog.Green("这是一个ED25519公钥\n") default: starlog.Green("未知公钥类型\n") } return common, certs, nil default: starlog.Infof("未知证书文件类型\n") } } } func Pkcs8(data []byte, pwd string, originName string, outpath string) error { keys, _, err := GetCert(data, pwd) if err != nil { return err } for _, v := range keys { if v == nil { continue } switch n := v.(type) { case *ecdsa.PrivateKey, *rsa.PrivateKey, *dsa.PrivateKey, *ed25519.PrivateKey, *ecdh.PrivateKey: data, err = x509.MarshalPKCS8PrivateKey(n) if err != nil { return err } err = os.WriteFile(outpath+"/"+originName+".pkcs8", pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: data}), 0644) if err != nil { return err } else { starlog.Green("已将私钥保存到%s\n", outpath+"/"+originName+".pkcs8") } case *ecdsa.PublicKey, *rsa.PublicKey, *dsa.PublicKey, *ed25519.PublicKey, *ecdh.PublicKey: data, err = x509.MarshalPKIXPublicKey(n) if err != nil { return err } err = os.WriteFile(outpath+"/"+originName+".pub.pkcs8", pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: data}), 0644) if err != nil { return err } else { starlog.Green("已将公钥保存到%s\n", outpath+"/"+originName+".pub.pkcs8") } } } return nil } func Pkcs1(data []byte, pwd string, originName string, outpath string) error { keys, _, err := GetCert(data, pwd) if err != nil { return err } for _, v := range keys { if v == nil { continue } switch n := v.(type) { case *rsa.PrivateKey: data = x509.MarshalPKCS1PrivateKey(n) if err != nil { return err } err = os.WriteFile(outpath+"/"+originName+".pkcs1", pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: data}), 0644) if err != nil { return err } else { starlog.Green("已将私钥保存到%s\n", outpath+"/"+originName+".pkcs8") } case *rsa.PublicKey: data = x509.MarshalPKCS1PublicKey(n) if err != nil { return err } err = os.WriteFile(outpath+"/"+originName+".pub.pkcs1", pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: data}), 0644) if err != nil { return err } else { starlog.Green("已将公钥保存到%s\n", outpath+"/"+originName+".pub.pkcs1") } } } return nil }