-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
111 lines (92 loc) · 2.31 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main // import "go-decrypto-pro"
import (
"bytes"
"encoding/pem"
"flag"
"fmt"
"github.com/martinlindhe/gogost/gost28147"
"github.com/martinlindhe/gogost/gost3410"
"github.com/martinlindhe/gogost/gost341194"
"go-decrypto-pro/cpc"
"go-decrypto-pro/pkcs8"
"go-decrypto-pro/util"
"math/big"
)
func main() {
var (
path string
passphrase string
)
flag.StringVar(&path, "path", "", "Container path")
flag.StringVar(&passphrase, "pass", "", "Container passphrase")
// Parse console arguments
flag.Parse()
// header
header, err := cpc.ReadHeader(path)
if err != nil {
panic(err)
}
// primaries
primary, err := cpc.ReadPrimary(path, "primary.key")
if err != nil {
panic(err)
}
// masks
masks, err := cpc.ReadMasks(path, "masks.key")
if err != nil {
panic(err)
}
// Get derived key from CPKDF
derivedKey, err := util.DeriveKey(gost341194.New(&gost28147.GostR3411_94_CryptoProParamSet), masks[1], []byte(passphrase))
if err != nil {
panic(err)
}
curve, err := gost3410.NewCurveFromParams(gost3410.CurveParamsGostR34102001CryptoProXchA)
if err != nil {
panic(err)
}
var key [32]byte
copy(key[:], derivedKey)
cipher := gost28147.NewCipher(key, &gost28147.Gost28147_CryptoProParamSetA)
decrypter := cipher.NewECBDecrypter()
primaryKey := make([]byte, 32)
decrypter.CryptBlocks(primaryKey, primary.PrimaryKey)
// Reverse primary key
util.Reverse(primaryKey)
pk := new(big.Int).SetBytes(primaryKey)
// Reverse mask
util.Reverse(masks[0])
m := new(big.Int).SetBytes(masks[0])
raw := new(big.Int).Mod(
new(big.Int).Mul(
pk,
new(big.Int).ModInverse(
m,
curve.Q,
),
),
curve.Q,
).Bytes()
util.Reverse(raw)
privateKey, err := gost3410.NewPrivateKey(curve, gost3410.Mode2001, raw)
if err != nil {
panic(err)
}
publicKey, err := privateKey.PublicKey()
if err != nil {
panic(err)
}
//fmt.Println(privateKey.Raw())
//fmt.Println(publicKey.Raw())
//fmt.Println(header.KeyContainerContent.Unknown3.Bytes)
if len(header.KeyContainerContent.BeginningOfPublicKey.Bytes) > 0 && bytes.HasPrefix(publicKey.Raw(), header.KeyContainerContent.BeginningOfPublicKey.Bytes) {
b, err := pkcs8.MarshalPrivateKey(privateKey)
if err != nil {
panic(err)
}
fmt.Println(string(pem.EncodeToMemory(&pem.Block{
Type: "GOST PRIVATE KEY",
Bytes: b,
})))
}
}