├── util
├── version.go
├── banner.go
└── log.go
├── .idea
├── modules.xml
├── p12tool.iml
└── workspace.xml
├── go.mod
├── vars
└── var.go
├── cmd
└── main.go
├── work
├── command.go
├── bruteforce.go
└── parse.go
├── .github
└── workflows
│ └── release.yml
├── .goreleaser.yml
├── LICENSE
├── common
└── flag.go
├── README.MD
└── go.sum
/util/version.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "runtime"
5 | "time"
6 | )
7 |
8 | var (
9 | Version = "1.0"
10 | GitCommit = "n/a"
11 | BuildDate = time.Now().Format("01/02/06")
12 | GoVersion = runtime.Version()
13 | Author = "Evi1cg"
14 | )
15 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module p12tool
2 |
3 | go 1.15
4 |
5 | require (
6 | github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
7 | github.com/fatih/color v1.10.0
8 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
9 | github.com/urfave/cli/v2 v2.3.0
10 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5
11 | )
12 |
--------------------------------------------------------------------------------
/vars/var.go:
--------------------------------------------------------------------------------
1 | package vars
2 |
3 | import (
4 | "p12tool/util"
5 | "sync"
6 | )
7 |
8 | var (
9 | Threads = 100
10 | DebugMode bool
11 | Cert string
12 | Pass string
13 | File string
14 | OutFile string
15 | Logger util.Logger
16 | CrackedPassword string
17 | Attempts int
18 | ResultsLock sync.RWMutex
19 | )
--------------------------------------------------------------------------------
/.idea/p12tool.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/util/banner.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import "fmt"
4 |
5 | func PrintBanner() {
6 | banner := `
7 | ██████╗ ██╗██████╗ ████████╗ ██████╗ ██████╗ ██╗
8 | ██╔══██╗███║╚════██╗╚══██╔══╝██╔═══██╗██╔═══██╗██║
9 | ██████╔╝╚██║ █████╔╝ ██║ ██║ ██║██║ ██║██║
10 | ██╔═══╝ ██║██╔═══╝ ██║ ██║ ██║██║ ██║██║
11 | ██║ ██║███████╗ ██║ ╚██████╔╝╚██████╔╝███████╗
12 | ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝
13 | `
14 | fmt.Printf("%v\nVersion: %v (%v) - %v - %v\n\n", banner, Version, GitCommit, BuildDate, Author)
15 | }
16 |
--------------------------------------------------------------------------------
/cmd/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/urfave/cli/v2"
5 | "log"
6 | "os"
7 | "p12tool/common"
8 | "p12tool/util"
9 | )
10 |
11 | func main() {
12 | util.PrintBanner()
13 | app := cli.NewApp()
14 | app.Name = "p12tool"
15 | app.Authors = []*cli.Author{
16 | &cli.Author{
17 | Name: "Evi1cg",
18 | }}
19 | app.Usage = "A tool to parse p12 cert file or bruteforce attacks against cert password"
20 | app.Commands = []*cli.Command{&common.Parse, &common.Crack}
21 | app.Flags = append(app.Flags,common.Flags...)
22 | err := app.Run(os.Args)
23 | if err != nil {
24 | log.Fatal(err)
25 | }
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/work/command.go:
--------------------------------------------------------------------------------
1 | package work
2 |
3 | import (
4 | "github.com/urfave/cli/v2"
5 | "p12tool/vars"
6 | )
7 |
8 | // 传入参数解析
9 | func Parse(ctx *cli.Context) (err error) {
10 | if ctx.IsSet("debug") {
11 | vars.DebugMode = ctx.Bool("debug")
12 | }
13 | if ctx.IsSet("cert"){
14 | vars.Cert = ctx.String("cert")
15 | }
16 | if ctx.IsSet("password"){
17 | vars.Pass = ctx.String("password")
18 | }
19 | if ctx.IsSet("file"){
20 | vars.File = ctx.String("file")
21 | }
22 | if ctx.IsSet("thread"){
23 | vars.Threads = ctx.Int("thread")
24 | }
25 | if ctx.IsSet("out"){
26 | vars.OutFile = ctx.String("out")
27 | }
28 | return err
29 | }
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: Release
4 | on:
5 | create:
6 | tags:
7 | - v*
8 |
9 | # Allows you to run this workflow manually from the Actions tab
10 | workflow_dispatch:
11 |
12 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
13 | jobs:
14 | goreleaser:
15 | runs-on: ubuntu-latest
16 | steps:
17 | -
18 | name: Checkout
19 | uses: actions/checkout@v2
20 | with:
21 | fetch-depth: 0
22 | -
23 | name: Set up Go
24 | uses: actions/setup-go@v2
25 | with:
26 | go-version: 1.15
27 | -
28 | name: Run GoReleaser
29 | uses: goreleaser/goreleaser-action@v2
30 | with:
31 | version: latest
32 | args: release --rm-dist
33 | env:
34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35 |
--------------------------------------------------------------------------------
/.goreleaser.yml:
--------------------------------------------------------------------------------
1 | # This is an example goreleaser.yaml file with some sane defaults.
2 | # Make sure to check the documentation at http://goreleaser.com
3 | before:
4 | hooks:
5 | # You may remove this if you don't use go modules.
6 | - go mod download
7 | # you may remove this if you don't need go generate
8 | - go generate ./...
9 | builds:
10 | - env:
11 | - CGO_ENABLED=0
12 | goos:
13 | - linux
14 | - windows
15 | - darwin
16 | main: ./cmd/main.go
17 |
18 | ldflags:
19 | - -s -w
20 |
21 | archives:
22 | - replacements:
23 | darwin: Darwin
24 | linux: Linux
25 | windows: Windows
26 | 386: i386
27 | amd64: x86_64
28 | checksum:
29 | name_template: 'checksums.txt'
30 |
31 | snapshot:
32 | name_template: "{{ .Tag }}-next"
33 |
34 | changelog:
35 | skip: true
36 | sort: asc
37 | filters:
38 | exclude:
39 | - '^docs:'
40 | - '^test:'
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Evi1cg
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/util/log.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "os"
5 |
6 | "github.com/op/go-logging"
7 | )
8 |
9 | type Logger struct {
10 | Log *logging.Logger
11 | }
12 |
13 | func NewLogger(verbose bool, logFileName string) Logger {
14 | log := logging.MustGetLogger("p12tool")
15 | format := logging.MustStringFormatter(
16 | `%{color}%{time:2006/01/02 15:04:05} -> %{message}%{color:reset}`,
17 | )
18 | formatNoColor := logging.MustStringFormatter(
19 | `%{time:2006/01/02 15:04:05} -> %{message}`,
20 | )
21 | backend := logging.NewLogBackend(os.Stdout, "", 0)
22 | backendFormatter := logging.NewBackendFormatter(backend, format)
23 |
24 | if logFileName != "" {
25 | outputFile, err := os.Create(logFileName)
26 | if err != nil {
27 | panic(err)
28 | }
29 | fileBackend := logging.NewLogBackend(outputFile, "", 0)
30 | fileFormatter := logging.NewBackendFormatter(fileBackend, formatNoColor)
31 | logging.SetBackend(backendFormatter, fileFormatter)
32 | } else {
33 | logging.SetBackend(backendFormatter)
34 | }
35 |
36 | if verbose {
37 | logging.SetLevel(logging.DEBUG, "")
38 | } else {
39 | logging.SetLevel(logging.INFO, "")
40 | }
41 | return Logger{log}
42 | }
43 |
--------------------------------------------------------------------------------
/common/flag.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "github.com/urfave/cli/v2"
5 | "p12tool/vars"
6 | "p12tool/work"
7 | )
8 |
9 |
10 |
11 | var Flags = []cli.Flag{
12 | &cli.StringFlag{Name: "cert", Aliases: []string{"c"},Usage: "The cert file you choice."},
13 | &cli.BoolFlag{Name: "debug", Aliases: []string{"d"}, Value: false, Usage: "Debug mode."},
14 | }
15 | var ParseFlag = []cli.Flag{
16 | &cli.StringFlag{Name: "password", Aliases: []string{"p"} ,Usage: "The cert file password."},
17 | }
18 | var BruteFlag = []cli.Flag{
19 | &cli.StringFlag{Name: "file", Aliases: []string{"f"} ,Usage: "The cert file password."},
20 | &cli.IntFlag{Name: "thread", Aliases: []string{"t"} , Value: vars.Threads ,Usage: "Crack thread num."},
21 | &cli.StringFlag{Name: "out", Aliases: []string{"o"} ,Usage: "Output file to save cracked password."},
22 | }
23 |
24 |
25 | var Parse = cli.Command{
26 | Name: "parse",
27 | Usage: "Parse p12 file and print cert info",
28 | Description: "Parse p12 file and print cert info",
29 | Action: work.ParseP12file,
30 | Flags: append(Flags, ParseFlag...),
31 | }
32 |
33 | var Crack = cli.Command{
34 | Name: "crack",
35 | Usage: "Crack p12 file password.",
36 | Description: "Crack p12 file password.",
37 | Action: work.P12FileBrute,
38 | Flags: append(Flags,BruteFlag...),
39 | }
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # P12tool
2 | 学习golang写的一个用来解析和爆破p12证书的小工具,代码写的有点戳,能用就行。
3 |
4 | ## Usage
5 | ```
6 |
7 | ██████╗ ██╗██████╗ ████████╗ ██████╗ ██████╗ ██╗
8 | ██╔══██╗███║╚════██╗╚══██╔══╝██╔═══██╗██╔═══██╗██║
9 | ██████╔╝╚██║ █████╔╝ ██║ ██║ ██║██║ ██║██║
10 | ██╔═══╝ ██║██╔═══╝ ██║ ██║ ██║██║ ██║██║
11 | ██║ ██║███████╗ ██║ ╚██████╔╝╚██████╔╝███████╗
12 | ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝
13 |
14 | Version: dev (n/a) - 12/31/20 - Evi1cg
15 |
16 | NAME:
17 | p12tool - A tool to parse p12 cert file or bruteforce attacks against cert password
18 |
19 | USAGE:
20 | main [global options] command [command options] [arguments...]
21 |
22 | AUTHOR:
23 | Evi1cg
24 |
25 | COMMANDS:
26 | parse Parse p12 file and print cert info
27 | crack Crack p12 file password.
28 | help, h Shows a list of commands or help for one command
29 |
30 | GLOBAL OPTIONS:
31 | --cert value, -c value The cert file you choice.
32 | --debug, -d Debug mode. (default: false)
33 | --help, -h show help (default: false)
34 | ```
35 |
36 | ## crack
37 | ```bash
38 | go run cmd/main.go crack -c file.pfx -f passwords.txt
39 | ```
40 | >可选: -t 指定线程,-d 开启debug模式,-o 将破解成功的密码输出至指定文件。
41 |
42 | 
43 |
44 |
45 | ## parse
46 | ```bash
47 | go run cmd/main.go parse -c file.pfx -p password
48 | ```
49 |
50 | 
51 |
52 | 对证书进行解析,输出证书信息,顺便输出是否可对程序进行签名,免去手动验证的烦恼。 ~~
53 |
54 | 2020年推得最后一个小工具,祝大家新年快乐!!
55 |
56 | ## 参考
57 | * 1、https://github.com/allyomalley/p12CrackerGo
58 | * 2、https://golang.org/pkg/crypto/x509
59 | * 3、https://godoc.org/golang.org/x/crypto/pkcs12
--------------------------------------------------------------------------------
/work/bruteforce.go:
--------------------------------------------------------------------------------
1 | package work
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "github.com/urfave/cli/v2"
7 | "golang.org/x/crypto/pkcs12"
8 | "io/ioutil"
9 | "os"
10 | "p12tool/util"
11 | "p12tool/vars"
12 | "strconv"
13 | )
14 |
15 | func P12FileBrute(ctx *cli.Context) (err error) {
16 | Parse(ctx)
17 | vars.Logger = util.NewLogger(vars.DebugMode, "")
18 | p12Bytes, err := ioutil.ReadFile(vars.Cert)
19 | if err != nil {
20 | vars.Logger.Log.Error("[-] Please input cert file")
21 | return nil
22 | }
23 | targetFile, err := os.Open(vars.File)
24 | if err != nil {
25 | vars.Logger.Log.Error("[-] Please input pass list file")
26 | return nil
27 | }
28 | scanner := bufio.NewScanner(targetFile)
29 | scanner.Split(bufio.ScanLines)
30 | vars.Logger.Log.Info("[*] Brute forcing...")
31 | crack(scanner, p12Bytes, vars.Threads)
32 | if vars.CrackedPassword !=""{
33 | success := fmt.Sprintf("[+] Password found ==> %s", vars.CrackedPassword)
34 | vars.Logger.Log.Noticef(success)
35 | if vars.OutFile != ""{
36 | fi, err := os.Create(vars.OutFile)
37 | if err != nil{
38 | vars.Logger.Log.Errorf("[!] Can't create file %s",vars.OutFile)
39 | }
40 | defer fi.Close()
41 | _, err2 := fi.WriteString(success)
42 | if err2 != nil {
43 | vars.Logger.Log.Errorf("[!] Write file error")
44 | }
45 | }
46 | vars.Logger.Log.Infof("[*] Successfully cracked password after " + strconv.Itoa(vars.Attempts) + " attempts!")
47 | }
48 | return err
49 | }
50 |
51 | func crack(scanner *bufio.Scanner, p12Bytes []byte, threads int) {
52 | vars.Logger.Log.Infof("[*] Start thread num %d",vars.Threads)
53 | semaphore := make(chan bool, threads)
54 | lineNo := 0
55 | for scanner.Scan() {
56 | lineNo = lineNo + 1
57 | semaphore <- true
58 |
59 | go func(password string, line int) {
60 | decrypted := checkPass(p12Bytes, password)
61 | if decrypted != "" {
62 | vars.ResultsLock.Lock()
63 | vars.Attempts = line
64 | vars.CrackedPassword = password
65 | vars.ResultsLock.Unlock()
66 | }
67 | <-semaphore
68 | }(scanner.Text(), lineNo)
69 | }
70 |
71 | for i := 0; i < cap(semaphore); i++ {
72 | semaphore <- true
73 | }
74 | }
75 | func checkPass(p12Bytes []byte, password string) string {
76 | _, err := pkcs12.ToPEM(p12Bytes, password)
77 | if err != nil{
78 | if err == pkcs12.ErrIncorrectPassword{
79 | if vars.DebugMode{
80 | vars.Logger.Log.Debugf("[-] Password [%s] incorrect",password)
81 | }
82 | }else{
83 | vars.Logger.Log.Error("[-] Check your file is P12 cert file !!")
84 | os.Exit(1)
85 | }
86 |
87 | }else{
88 | return password
89 | }
90 | return ""
91 | }
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
3 | github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
4 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
5 | github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
6 | github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
7 | github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
8 | github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
9 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
10 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
11 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
12 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
13 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
14 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
15 | github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
16 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
17 | github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
18 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
19 | github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
20 | github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
21 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
22 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
23 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
24 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
25 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
26 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
27 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
28 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
29 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
30 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
31 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
32 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
33 |
--------------------------------------------------------------------------------
/work/parse.go:
--------------------------------------------------------------------------------
1 | package work
2 |
3 | import (
4 | "bytes"
5 | "crypto/tls"
6 | "crypto/x509"
7 | "encoding/pem"
8 | "fmt"
9 | "github.com/urfave/cli/v2"
10 | "io/ioutil"
11 | "log"
12 | "p12tool/util"
13 | "p12tool/vars"
14 |
15 | "golang.org/x/crypto/pkcs12"
16 | )
17 |
18 | func ParseP12file(ctx *cli.Context) (err error) {
19 | Parse(ctx)
20 | vars.Logger = util.NewLogger(vars.DebugMode, "")
21 | p12Bytes, err := ioutil.ReadFile(vars.Cert)
22 | if err != nil {
23 | vars.Logger.Log.Error("[-] Please input cert file")
24 | return nil
25 | }
26 | pass := vars.Pass
27 | if len(pass) == 0{
28 | vars.Logger.Log.Error("[-] Please input a password")
29 | return nil
30 | }
31 | // P12 to PEM
32 | blocks, err := pkcs12.ToPEM(p12Bytes, pass)
33 |
34 | if err != nil{
35 | if err == pkcs12.ErrIncorrectPassword{
36 | vars.Logger.Log.Error("[-] Password incorrect")
37 | }else{
38 | vars.Logger.Log.Error("[-] Check your file is P12 cert file !!")
39 | }
40 | return nil
41 | }
42 | // Append all PEM Blocks together
43 | var pemData []byte
44 | for _, b := range blocks {
45 | pemData = append(pemData, pem.EncodeToMemory(b)...)
46 | }
47 | vars.Logger.Log.Notice("[+] Parse cert file ok ;)")
48 | //println(PemPrivateKeyFromPem(string(pemData)))
49 | //println(PemCertFromPem(string(pemData)))
50 | block, rest := pem.Decode([]byte(PemCertFromPem(string(pemData))))
51 | if block == nil || len(rest) > 0 {
52 | log.Fatal("Certificate decoding error")
53 | return nil
54 | }
55 | cert, err := x509.ParseCertificate(block.Bytes)
56 | if err != nil {
57 | log.Fatal(err)
58 | }
59 | fmt.Printf("=============================INFO===========================\nCommonName:\t\t%s\nCountry:\t\t%s\nOrganization:\t\t%s\nLocality:\t\t%s\nNotAfter:\t\t%s\n============================================================\n",cert.Subject.CommonName,cert.Subject.Country,cert.Subject.Organization,cert.Subject.Locality,cert.NotAfter)
60 | for i := range cert.ExtKeyUsage{
61 | if cert.ExtKeyUsage[i] == 0 || cert.ExtKeyUsage[i] == 3{
62 | vars.Logger.Log.Notice("[+] Can be used for code signing!!;)")
63 | return nil
64 | }
65 | }
66 | vars.Logger.Log.Error("[-] Not suitable for code signing ;(")
67 | return err
68 | }
69 |
70 |
71 | func PemPrivateKeyFromPem(data string) string {
72 | pemBytes := []byte(data)
73 |
74 | // Use tls lib to construct tls certificate and key object from PEM data
75 | // The tls.X509KeyPair function is smart enough to parse combined cert and key pem data
76 | certAndKey, err := tls.X509KeyPair(pemBytes, pemBytes)
77 | if err != nil {
78 | panic(err)
79 | }
80 |
81 | // Get parsed private key as PKCS8 data
82 | privBytes, err := x509.MarshalPKCS8PrivateKey(certAndKey.PrivateKey)
83 | if err != nil {
84 | panic(fmt.Sprintf("Unable to marshal private key: %v", err))
85 | }
86 |
87 | // Encode just the private key back to PEM and return it
88 | var privPem bytes.Buffer
89 | if err := pem.Encode(&privPem, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
90 | panic(fmt.Sprintf("Failed to write data: %s", err))
91 | }
92 |
93 | return privPem.String()
94 | }
95 |
96 | func PemCertFromPem(data string) string {
97 | pemBytes := []byte(data)
98 |
99 | // Use tls lib to construct tls certificate and key object from PEM data
100 | // The tls.X509KeyPair function is smart enough to parse combined cert and key pem data
101 | certAndKey, err := tls.X509KeyPair(pemBytes, pemBytes)
102 | if err != nil {
103 | panic(fmt.Sprintf("Error generating X509KeyPair: %v", err))
104 | }
105 |
106 | leaf, err := x509.ParseCertificate(certAndKey.Certificate[0])
107 | if err != nil {
108 | panic(err)
109 | }
110 |
111 | // Encode just the leaf cert as pem
112 | var certPem bytes.Buffer
113 | if err := pem.Encode(&certPem, &pem.Block{Type: "CERTIFICATE", Bytes: leaf.Raw}); err != nil {
114 | panic(fmt.Sprintf("Failed to write data: %s", err))
115 | }
116 |
117 | return certPem.String()
118 | }
119 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | true
94 |
95 |
--------------------------------------------------------------------------------