diff --git a/internal/browingdata/cookie/cookie.go b/internal/browingdata/cookie/cookie.go index 08aca0a3..437b2fff 100644 --- a/internal/browingdata/cookie/cookie.go +++ b/internal/browingdata/cookie/cookie.go @@ -75,7 +75,7 @@ func (c *ChromiumCookie) Parse(masterKey []byte) error { if masterKey == nil { value, err = decrypter.DPApi(encryptValue) } else { - value, err = decrypter.ChromePass(masterKey, encryptValue) + value, err = decrypter.Chromium(masterKey, encryptValue) } if err != nil { log.Error(err) diff --git a/internal/browingdata/creditcard/creditcard.go b/internal/browingdata/creditcard/creditcard.go index 40bd8119..75eeee57 100644 --- a/internal/browingdata/creditcard/creditcard.go +++ b/internal/browingdata/creditcard/creditcard.go @@ -61,7 +61,7 @@ func (c *ChromiumCreditCard) Parse(masterKey []byte) error { return err } } else { - value, err = decrypter.ChromePass(masterKey, encryptValue) + value, err = decrypter.Chromium(masterKey, encryptValue) if err != nil { return err } @@ -112,7 +112,7 @@ func (c *YandexCreditCard) Parse(masterKey []byte) error { return err } } else { - value, err = decrypter.ChromePassForYandex(masterKey, encryptValue) + value, err = decrypter.Chromium(masterKey, encryptValue) if err != nil { return err } diff --git a/internal/browingdata/password/password.go b/internal/browingdata/password/password.go index 064efc61..e79b9de0 100644 --- a/internal/browingdata/password/password.go +++ b/internal/browingdata/password/password.go @@ -65,7 +65,7 @@ func (c *ChromiumPassword) Parse(masterKey []byte) error { if masterKey == nil { password, err = decrypter.DPApi(pwd) } else { - password, err = decrypter.ChromePass(masterKey, pwd) + password, err = decrypter.Chromium(masterKey, pwd) } if err != nil { log.Error(err) @@ -129,7 +129,7 @@ func (c *YandexPassword) Parse(masterKey []byte) error { if masterKey == nil { password, err = decrypter.DPApi(pwd) } else { - password, err = decrypter.ChromePassForYandex(masterKey, pwd) + password, err = decrypter.Chromium(masterKey, pwd) } if err != nil { log.Errorf("decrypt yandex password error %s", err) diff --git a/internal/decrypter/decrypter.go b/internal/decrypter/decrypter.go index 88b40819..a00c3f38 100644 --- a/internal/decrypter/decrypter.go +++ b/internal/decrypter/decrypter.go @@ -27,9 +27,9 @@ type ASN1PBE interface { func NewASN1PBE(b []byte) (pbe ASN1PBE, err error) { var ( - n NssPBE - m MetaPBE - l LoginPBE + n nssPBE + m metaPBE + l loginPBE ) if _, err := asn1.Unmarshal(b, &n); err == nil { return n, nil @@ -43,7 +43,7 @@ func NewASN1PBE(b []byte) (pbe ASN1PBE, err error) { return nil, errDecodeASN1Failed } -// NssPBE Struct +// nssPBE Struct // SEQUENCE (2 elem) // SEQUENCE (2 elem) // OBJECT IDENTIFIER @@ -51,33 +51,33 @@ func NewASN1PBE(b []byte) (pbe ASN1PBE, err error) { // OCTET STRING (20 byte) // INTEGER 1 // OCTET STRING (16 byte) -type NssPBE struct { - NssSequenceA +type nssPBE struct { + AlgoAttr struct { + asn1.ObjectIdentifier + SaltAttr struct { + EntrySalt []byte + Len int + } + } Encrypted []byte } -type NssSequenceA struct { - DecryptMethod asn1.ObjectIdentifier - NssSequenceB -} - -type NssSequenceB struct { - EntrySalt []byte - Len int +func (n nssPBE) entrySalt() []byte { + return n.AlgoAttr.SaltAttr.EntrySalt } -func (n NssPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) { +func (n nssPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) { glmp := append(globalSalt, masterPwd...) hp := sha1.Sum(glmp) - s := append(hp[:], n.EntrySalt...) + s := append(hp[:], n.entrySalt()...) chp := sha1.Sum(s) - pes := paddingZero(n.EntrySalt, 20) + pes := paddingZero(n.entrySalt(), 20) tk := hmac.New(sha1.New, chp[:]) tk.Write(pes) - pes = append(pes, n.EntrySalt...) + pes = append(pes, n.entrySalt()...) k1 := hmac.New(sha1.New, chp[:]) k1.Write(pes) - tkPlus := append(tk.Sum(nil), n.EntrySalt...) + tkPlus := append(tk.Sum(nil), n.entrySalt()...) k2 := hmac.New(sha1.New, chp[:]) k2.Write(tkPlus) k := append(k1.Sum(nil), k2.Sum(nil)...) @@ -102,68 +102,73 @@ func (n NssPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) { // OBJECT IDENTIFIER // OCTET STRING (14 byte) // OCTET STRING (16 byte) -type MetaPBE struct { - MetaSequenceA +type metaPBE struct { + AlgoAttr algoAttr Encrypted []byte } -type MetaSequenceA struct { - PKCS5PBES2 asn1.ObjectIdentifier - MetaSequenceB -} -type MetaSequenceB struct { - MetaSequenceC - MetaSequenceD -} - -type MetaSequenceC struct { - PKCS5PBKDF2 asn1.ObjectIdentifier - MetaSequenceE +type algoAttr struct { + asn1.ObjectIdentifier + Data struct { + Data struct { + asn1.ObjectIdentifier + SlatAttr slatAttr + } + IVData ivAttr + } } -type MetaSequenceD struct { - AES256CBC asn1.ObjectIdentifier - IV []byte +type ivAttr struct { + asn1.ObjectIdentifier + IV []byte } -type MetaSequenceE struct { +type slatAttr struct { EntrySalt []byte IterationCount int KeySize int - MetaSequenceF -} - -type MetaSequenceF struct { - HMACWithSHA256 asn1.ObjectIdentifier + Algorithm struct { + asn1.ObjectIdentifier + } } -func (m MetaPBE) Decrypt(globalSalt, masterPwd []byte) (key2 []byte, err error) { +func (m metaPBE) Decrypt(globalSalt, masterPwd []byte) (key2 []byte, err error) { k := sha1.Sum(globalSalt) - key := pbkdf2.Key(k[:], m.EntrySalt, m.IterationCount, m.KeySize, sha256.New) - iv := append([]byte{4, 14}, m.IV...) + key := pbkdf2.Key(k[:], m.entrySalt(), m.iterationCount(), m.keySize(), sha256.New) + iv := append([]byte{4, 14}, m.AlgoAttr.Data.IVData.IV...) return aes128CBCDecrypt(key, iv, m.Encrypted) } -// LoginPBE Struct +func (m metaPBE) entrySalt() []byte { + return m.AlgoAttr.Data.Data.SlatAttr.EntrySalt +} + +func (m metaPBE) iterationCount() int { + return m.AlgoAttr.Data.Data.SlatAttr.IterationCount +} + +func (m metaPBE) keySize() int { + return m.AlgoAttr.Data.Data.SlatAttr.KeySize +} + +// loginPBE Struct // SEQUENCE (3 elem) // OCTET STRING (16 byte) // SEQUENCE (2 elem) // OBJECT IDENTIFIER // OCTET STRING (8 byte) // OCTET STRING (16 byte) -type LoginPBE struct { +type loginPBE struct { CipherText []byte - LoginSequence + Data struct { + asn1.ObjectIdentifier + IV []byte + } Encrypted []byte } -type LoginSequence struct { - asn1.ObjectIdentifier - IV []byte -} - -func (l LoginPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) { - return des3Decrypt(globalSalt, l.IV, l.Encrypted) +func (l loginPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) { + return des3Decrypt(globalSalt, l.Data.IV, l.Encrypted) } func aes128CBCDecrypt(key, iv, encryptPass []byte) ([]byte, error) { diff --git a/internal/decrypter/decrypter_darwin.go b/internal/decrypter/decrypter_darwin.go index 24496c5a..945dc37c 100644 --- a/internal/decrypter/decrypter_darwin.go +++ b/internal/decrypter/decrypter_darwin.go @@ -1,6 +1,6 @@ package decrypter -func ChromePass(key, encryptPass []byte) ([]byte, error) { +func Chromium(key, encryptPass []byte) ([]byte, error) { if len(encryptPass) > 3 { if len(key) == 0 { return nil, errSecurityKeyIsEmpty diff --git a/internal/decrypter/decrypter_linux.go b/internal/decrypter/decrypter_linux.go index a56a46e6..d584f093 100644 --- a/internal/decrypter/decrypter_linux.go +++ b/internal/decrypter/decrypter_linux.go @@ -1,6 +1,6 @@ package decrypter -func ChromePass(key, encryptPass []byte) ([]byte, error) { +func Chromium(key, encryptPass []byte) ([]byte, error) { var chromeIV = []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32} if len(encryptPass) > 3 { if len(key) == 0 { diff --git a/internal/decrypter/decrypter_windows.go b/internal/decrypter/decrypter_windows.go index debc8f47..25692496 100644 --- a/internal/decrypter/decrypter_windows.go +++ b/internal/decrypter/decrypter_windows.go @@ -7,7 +7,7 @@ import ( "unsafe" ) -func ChromePass(key, encryptPass []byte) ([]byte, error) { +func Chromium(key, encryptPass []byte) ([]byte, error) { if len(encryptPass) > 15 { // remove Prefix 'v10' return aesGCMDecrypt(encryptPass[15:], key, encryptPass[3:15]) @@ -16,7 +16,7 @@ func ChromePass(key, encryptPass []byte) ([]byte, error) { } } -func ChromePassForYandex(key, encryptPass []byte) ([]byte, error) { +func ChromiumForYandex(key, encryptPass []byte) ([]byte, error) { if len(encryptPass) > 15 { // remove Prefix 'v10' // gcmBlockSize = 16