/
iblfile_legacyenc.go
99 lines (75 loc) · 2.36 KB
/
iblfile_legacyenc.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
// From https://github.com/InfinityBotList/iblfile/blob/7d02b1ba186e0d6211330ae3d5442521345f90c1/consts.go
package iblfile_legacyenc
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/sha512"
"crypto/x509"
"encoding/pem"
"fmt"
)
// The number of keys to encrypt the data with
//
// Note that changing keycount does not need a change in protocol version
const KeyCount = 16
type PemEncryptionData struct {
// Public key to encrypt data with
PEM []byte `json:"p"`
// Encrypted OEAP keys
Keys [][]byte `json:"k"`
// Encryption nonce
Nonce string `json:"n"`
// Whether or not symmetric encryption is being used
//
// If this option is set, then a `privKey` section MUST be present (e.g. using an AutoEncrypted file)
Symmetric bool `json:"s"`
}
func DecryptData(encData *bytes.Buffer, enc *PemEncryptionData, privkey []byte) (*bytes.Buffer, error) {
var decrPass = []byte(enc.Nonce)
for _, key := range enc.Keys {
hash := sha512.New()
random := rand.Reader
pem, _ := pem.Decode(privkey)
if pem == nil {
return nil, fmt.Errorf("failed to decode private key file")
}
privInterface, parseErr := x509.ParsePKCS8PrivateKey(pem.Bytes)
if parseErr != nil {
return nil, fmt.Errorf("failed to parse private key: %s", parseErr)
}
priv := privInterface.(*rsa.PrivateKey)
msg, err := rsa.DecryptOAEP(hash, random, priv, key, nil)
if err != nil {
return nil, fmt.Errorf("failed to decrypt data: %s", err)
}
decrPass = append(decrPass, msg...)
}
// Decrypt backupBuf with encryptedKey using aes-512-gcm
keyHash := sha256.New()
keyHash.Write(decrPass)
c, err := aes.NewCipher(keyHash.Sum(nil))
if err != nil {
return nil, fmt.Errorf("failed to create cipher: %s", err)
}
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, fmt.Errorf("failed to create gcm: %s", err)
}
nonceSize := gcm.NonceSize()
// Extract nonce from encrypted data which is a bytes buffer
aesNonce := encData.Next(nonceSize)
if len(aesNonce) != nonceSize {
return nil, fmt.Errorf("failed to extract nonce from encrypted data: %d != %d", len(aesNonce), nonceSize)
}
encData = bytes.NewBuffer(encData.Bytes())
// Decrypt data
decData, err := gcm.Open(nil, aesNonce, encData.Bytes(), nil)
if err != nil {
return nil, fmt.Errorf("failed to decrypt data: %s", err)
}
return bytes.NewBuffer(decData), nil
}