crypt.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. // Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
  2. // this source code is governed by a BSD-style license that can be found in
  3. // the LICENSE file.
  4. //
  5. // Package excelize providing a set of functions that allow you to write to
  6. // and read from XLSX files. Support reads and writes XLSX file generated by
  7. // Microsoft Excel™ 2007 and later. Support save file without losing original
  8. // charts of XLSX. This library needs Go version 1.10 or later.
  9. package excelize
  10. import (
  11. "bytes"
  12. "crypto/aes"
  13. "crypto/cipher"
  14. "crypto/hmac"
  15. "crypto/md5"
  16. "crypto/sha1"
  17. "crypto/sha256"
  18. "crypto/sha512"
  19. "encoding/base64"
  20. "encoding/binary"
  21. "encoding/xml"
  22. "errors"
  23. "hash"
  24. "math/rand"
  25. "reflect"
  26. "strings"
  27. "github.com/richardlehane/mscfb"
  28. "golang.org/x/crypto/md4"
  29. "golang.org/x/crypto/ripemd160"
  30. "golang.org/x/text/encoding/unicode"
  31. )
  32. var (
  33. blockKey = []byte{0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6} // Block keys used for encryption
  34. blockKeyHmacKey = []byte{0x5f, 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, 0xf6}
  35. blockKeyHmacValue = []byte{0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, 0x33}
  36. blockKeyVerifierHashInput = []byte{0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, 0x79}
  37. blockKeyVerifierHashValue = []byte{0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e}
  38. packageOffset = 8 // First 8 bytes are the size of the stream
  39. packageEncryptionChunkSize = 4096
  40. iterCount = 50000
  41. cryptoIdentifier = []byte{ // checking protect workbook by [MS-OFFCRYPTO] - v20181211 3.1 FeatureIdentifier
  42. 0x3c, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00,
  43. 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00,
  44. 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x2e, 0x00, 0x44, 0x00, 0x61, 0x00,
  45. 0x74, 0x00, 0x61, 0x00, 0x53, 0x00, 0x70, 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00,
  46. 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  47. }
  48. oleIdentifier = []byte{
  49. 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1,
  50. }
  51. )
  52. // Encryption specifies the encryption structure, streams, and storages are
  53. // required when encrypting ECMA-376 documents.
  54. type Encryption struct {
  55. XMLName xml.Name `xml:"encryption"`
  56. KeyData KeyData `xml:"keyData"`
  57. DataIntegrity DataIntegrity `xml:"dataIntegrity"`
  58. KeyEncryptors KeyEncryptors `xml:"keyEncryptors"`
  59. }
  60. // KeyData specifies the cryptographic attributes used to encrypt the data.
  61. type KeyData struct {
  62. SaltSize int `xml:"saltSize,attr"`
  63. BlockSize int `xml:"blockSize,attr"`
  64. KeyBits int `xml:"keyBits,attr"`
  65. HashSize int `xml:"hashSize,attr"`
  66. CipherAlgorithm string `xml:"cipherAlgorithm,attr"`
  67. CipherChaining string `xml:"cipherChaining,attr"`
  68. HashAlgorithm string `xml:"hashAlgorithm,attr"`
  69. SaltValue string `xml:"saltValue,attr"`
  70. }
  71. // DataIntegrity specifies the encrypted copies of the salt and hash values
  72. // used to help ensure that the integrity of the encrypted data has not been
  73. // compromised.
  74. type DataIntegrity struct {
  75. EncryptedHmacKey string `xml:"encryptedHmacKey,attr"`
  76. EncryptedHmacValue string `xml:"encryptedHmacValue,attr"`
  77. }
  78. // KeyEncryptors specifies the key encryptors used to encrypt the data.
  79. type KeyEncryptors struct {
  80. KeyEncryptor []KeyEncryptor `xml:"keyEncryptor"`
  81. }
  82. // KeyEncryptor specifies that the schema used by this encryptor is the schema
  83. // specified for password-based encryptors.
  84. type KeyEncryptor struct {
  85. XMLName xml.Name `xml:"keyEncryptor"`
  86. URI string `xml:"uri,attr"`
  87. EncryptedKey EncryptedKey `xml:"encryptedKey"`
  88. }
  89. // EncryptedKey used to generate the encrypting key.
  90. type EncryptedKey struct {
  91. XMLName xml.Name `xml:"http://schemas.microsoft.com/office/2006/keyEncryptor/password encryptedKey"`
  92. SpinCount int `xml:"spinCount,attr"`
  93. EncryptedVerifierHashInput string `xml:"encryptedVerifierHashInput,attr"`
  94. EncryptedVerifierHashValue string `xml:"encryptedVerifierHashValue,attr"`
  95. EncryptedKeyValue string `xml:"encryptedKeyValue,attr"`
  96. KeyData
  97. }
  98. // StandardEncryptionHeader structure is used by ECMA-376 document encryption
  99. // [ECMA-376] and Office binary document RC4 CryptoAPI encryption, to specify
  100. // encryption properties for an encrypted stream.
  101. type StandardEncryptionHeader struct {
  102. Flags uint32
  103. SizeExtra uint32
  104. AlgID uint32
  105. AlgIDHash uint32
  106. KeySize uint32
  107. ProviderType uint32
  108. Reserved1 uint32
  109. Reserved2 uint32
  110. CspName string
  111. }
  112. // StandardEncryptionVerifier structure is used by Office Binary Document RC4
  113. // CryptoAPI Encryption and ECMA-376 Document Encryption. Every usage of this
  114. // structure MUST specify the hashing algorithm and encryption algorithm used
  115. // in the EncryptionVerifier structure.
  116. type StandardEncryptionVerifier struct {
  117. SaltSize uint32
  118. Salt []byte
  119. EncryptedVerifier []byte
  120. VerifierHashSize uint32
  121. EncryptedVerifierHash []byte
  122. }
  123. // Decrypt API decrypt the CFB file format with ECMA-376 agile encryption and
  124. // standard encryption. Support cryptographic algorithm: MD4, MD5, RIPEMD-160,
  125. // SHA1, SHA256, SHA384 and SHA512 currently.
  126. func Decrypt(raw []byte, opt *Options) (packageBuf []byte, err error) {
  127. doc, err := mscfb.New(bytes.NewReader(raw))
  128. if err != nil {
  129. return
  130. }
  131. encryptionInfoBuf, encryptedPackageBuf := extractPart(doc)
  132. mechanism, err := encryptionMechanism(encryptionInfoBuf)
  133. if err != nil || mechanism == "extensible" {
  134. return
  135. }
  136. switch mechanism {
  137. case "agile":
  138. return agileDecrypt(encryptionInfoBuf, encryptedPackageBuf, opt)
  139. case "standard":
  140. return standardDecrypt(encryptionInfoBuf, encryptedPackageBuf, opt)
  141. default:
  142. err = errors.New("unsupport encryption mechanism")
  143. break
  144. }
  145. return
  146. }
  147. // Encrypt API encrypt data with the password.
  148. func Encrypt(raw []byte, opt *Options) (packageBuf []byte, err error) {
  149. // Generate a random key to use to encrypt the document. Excel uses 32 bytes. We'll use the password to encrypt this key.
  150. packageKey, _ := randomBytes(32)
  151. keyDataSaltValue, _ := randomBytes(16)
  152. keyEncryptors, _ := randomBytes(16)
  153. encryptionInfo := Encryption{
  154. KeyData: KeyData{
  155. BlockSize: 16,
  156. KeyBits: len(packageKey) * 8,
  157. HashSize: 64,
  158. CipherAlgorithm: "AES",
  159. CipherChaining: "ChainingModeCBC",
  160. HashAlgorithm: "SHA512",
  161. SaltValue: base64.StdEncoding.EncodeToString(keyDataSaltValue),
  162. },
  163. KeyEncryptors: KeyEncryptors{KeyEncryptor: []KeyEncryptor{{
  164. EncryptedKey: EncryptedKey{SpinCount: 100000, KeyData: KeyData{
  165. CipherAlgorithm: "AES",
  166. CipherChaining: "ChainingModeCBC",
  167. HashAlgorithm: "SHA512",
  168. HashSize: 64,
  169. BlockSize: 16,
  170. KeyBits: 256,
  171. SaltValue: base64.StdEncoding.EncodeToString(keyEncryptors)},
  172. }}},
  173. },
  174. }
  175. // Package Encryption
  176. // Encrypt package using the package key.
  177. encryptedPackage, err := cryptPackage(true, packageKey, raw, encryptionInfo)
  178. if err != nil {
  179. return
  180. }
  181. // Data Integrity
  182. // Create the data integrity fields used by clients for integrity checks.
  183. // Generate a random array of bytes to use in HMAC. The docs say to use the same length as the key salt, but Excel seems to use 64.
  184. hmacKey, _ := randomBytes(64)
  185. if err != nil {
  186. return
  187. }
  188. // Create an initialization vector using the package encryption info and the appropriate block key.
  189. hmacKeyIV, err := createIV(blockKeyHmacKey, encryptionInfo)
  190. if err != nil {
  191. return
  192. }
  193. // Use the package key and the IV to encrypt the HMAC key.
  194. encryptedHmacKey, err := crypt(true, encryptionInfo.KeyData.CipherAlgorithm, encryptionInfo.KeyData.CipherChaining, packageKey, hmacKeyIV, hmacKey)
  195. // Create the HMAC.
  196. h := hmac.New(sha512.New, append(hmacKey, encryptedPackage...))
  197. for _, buf := range [][]byte{hmacKey, encryptedPackage} {
  198. h.Write(buf)
  199. }
  200. hmacValue := h.Sum(nil)
  201. // Generate an initialization vector for encrypting the resulting HMAC value.
  202. hmacValueIV, err := createIV(blockKeyHmacValue, encryptionInfo)
  203. if err != nil {
  204. return
  205. }
  206. // Encrypt the value.
  207. encryptedHmacValue, err := crypt(true, encryptionInfo.KeyData.CipherAlgorithm, encryptionInfo.KeyData.CipherChaining, packageKey, hmacValueIV, hmacValue)
  208. // Put the encrypted key and value on the encryption info.
  209. encryptionInfo.DataIntegrity.EncryptedHmacKey = base64.StdEncoding.EncodeToString(encryptedHmacKey)
  210. encryptionInfo.DataIntegrity.EncryptedHmacValue = base64.StdEncoding.EncodeToString(encryptedHmacValue)
  211. // Key Encryption
  212. // Convert the password to an encryption key.
  213. key, err := convertPasswdToKey(opt.Password, blockKey, encryptionInfo)
  214. if err != nil {
  215. return
  216. }
  217. // Encrypt the package key with the encryption key.
  218. encryptedKeyValue, err := crypt(true, encryptionInfo.KeyEncryptors.KeyEncryptor[0].EncryptedKey.CipherAlgorithm, encryptionInfo.KeyEncryptors.KeyEncryptor[0].EncryptedKey.CipherChaining, key, keyEncryptors, packageKey)
  219. encryptionInfo.KeyEncryptors.KeyEncryptor[0].EncryptedKey.EncryptedKeyValue = base64.StdEncoding.EncodeToString(encryptedKeyValue)
  220. // Verifier hash
  221. // Create a random byte array for hashing.
  222. verifierHashInput, _ := randomBytes(16)
  223. // Create an encryption key from the password for the input.
  224. verifierHashInputKey, err := convertPasswdToKey(opt.Password, blockKeyVerifierHashInput, encryptionInfo)
  225. if err != nil {
  226. return
  227. }
  228. // Use the key to encrypt the verifier input.
  229. encryptedVerifierHashInput, err := crypt(true, encryptionInfo.KeyData.CipherAlgorithm, encryptionInfo.KeyData.CipherChaining, verifierHashInputKey, keyEncryptors, verifierHashInput)
  230. if err != nil {
  231. return
  232. }
  233. encryptionInfo.KeyEncryptors.KeyEncryptor[0].EncryptedKey.EncryptedVerifierHashInput = base64.StdEncoding.EncodeToString(encryptedVerifierHashInput)
  234. // Create a hash of the input.
  235. verifierHashValue := hashing(encryptionInfo.KeyData.HashAlgorithm, verifierHashInput)
  236. // Create an encryption key from the password for the hash.
  237. verifierHashValueKey, err := convertPasswdToKey(opt.Password, blockKeyVerifierHashValue, encryptionInfo)
  238. if err != nil {
  239. return
  240. }
  241. // Use the key to encrypt the hash value.
  242. encryptedVerifierHashValue, err := crypt(true, encryptionInfo.KeyData.CipherAlgorithm, encryptionInfo.KeyData.CipherChaining, verifierHashValueKey, keyEncryptors, verifierHashValue)
  243. if err != nil {
  244. return
  245. }
  246. encryptionInfo.KeyEncryptors.KeyEncryptor[0].EncryptedKey.EncryptedVerifierHashValue = base64.StdEncoding.EncodeToString(encryptedVerifierHashValue)
  247. // Marshal the encryption info buffer.
  248. encryptionInfoBuffer, err := xml.Marshal(encryptionInfo)
  249. if err != nil {
  250. return
  251. }
  252. // TODO: Create a new CFB.
  253. _, _ = encryptedPackage, encryptionInfoBuffer
  254. err = errors.New("not support encryption currently")
  255. return
  256. }
  257. // extractPart extract data from storage by specified part name.
  258. func extractPart(doc *mscfb.Reader) (encryptionInfoBuf, encryptedPackageBuf []byte) {
  259. for entry, err := doc.Next(); err == nil; entry, err = doc.Next() {
  260. switch entry.Name {
  261. case "EncryptionInfo":
  262. buf := make([]byte, entry.Size)
  263. i, _ := doc.Read(buf)
  264. if i > 0 {
  265. encryptionInfoBuf = buf
  266. break
  267. }
  268. case "EncryptedPackage":
  269. buf := make([]byte, entry.Size)
  270. i, _ := doc.Read(buf)
  271. if i > 0 {
  272. encryptedPackageBuf = buf
  273. break
  274. }
  275. }
  276. }
  277. return
  278. }
  279. // encryptionMechanism parse password-protected documents created mechanism.
  280. func encryptionMechanism(buffer []byte) (mechanism string, err error) {
  281. if len(buffer) < 4 {
  282. err = errors.New("unknown encryption mechanism")
  283. return
  284. }
  285. versionMajor, versionMinor := binary.LittleEndian.Uint16(buffer[0:2]), binary.LittleEndian.Uint16(buffer[2:4])
  286. if versionMajor == 4 && versionMinor == 4 {
  287. mechanism = "agile"
  288. return
  289. } else if (2 <= versionMajor && versionMajor <= 4) && versionMinor == 2 {
  290. mechanism = "standard"
  291. return
  292. } else if (versionMajor == 3 || versionMajor == 4) && versionMinor == 3 {
  293. mechanism = "extensible"
  294. }
  295. err = errors.New("unsupport encryption mechanism")
  296. return
  297. }
  298. // ECMA-376 Standard Encryption
  299. // standardDecrypt decrypt the CFB file format with ECMA-376 standard encryption.
  300. func standardDecrypt(encryptionInfoBuf, encryptedPackageBuf []byte, opt *Options) ([]byte, error) {
  301. encryptionHeaderSize := binary.LittleEndian.Uint32(encryptionInfoBuf[8:12])
  302. block := encryptionInfoBuf[12 : 12+encryptionHeaderSize]
  303. header := StandardEncryptionHeader{
  304. Flags: binary.LittleEndian.Uint32(block[:4]),
  305. SizeExtra: binary.LittleEndian.Uint32(block[4:8]),
  306. AlgID: binary.LittleEndian.Uint32(block[8:12]),
  307. AlgIDHash: binary.LittleEndian.Uint32(block[12:16]),
  308. KeySize: binary.LittleEndian.Uint32(block[16:20]),
  309. ProviderType: binary.LittleEndian.Uint32(block[20:24]),
  310. Reserved1: binary.LittleEndian.Uint32(block[24:28]),
  311. Reserved2: binary.LittleEndian.Uint32(block[28:32]),
  312. CspName: string(block[32:]),
  313. }
  314. block = encryptionInfoBuf[12+encryptionHeaderSize:]
  315. algIDMap := map[uint32]string{
  316. 0x0000660E: "AES-128",
  317. 0x0000660F: "AES-192",
  318. 0x00006610: "AES-256",
  319. }
  320. algorithm := "AES"
  321. _, ok := algIDMap[header.AlgID]
  322. if !ok {
  323. algorithm = "RC4"
  324. }
  325. verifier := standardEncryptionVerifier(algorithm, block)
  326. secretKey, err := standardConvertPasswdToKey(header, verifier, opt)
  327. if err != nil {
  328. return nil, err
  329. }
  330. // decrypted data
  331. x := encryptedPackageBuf[8:]
  332. blob, err := aes.NewCipher(secretKey)
  333. if err != nil {
  334. return nil, err
  335. }
  336. decrypted := make([]byte, len(x))
  337. size := 16
  338. for bs, be := 0, size; bs < len(x); bs, be = bs+size, be+size {
  339. blob.Decrypt(decrypted[bs:be], x[bs:be])
  340. }
  341. return decrypted, err
  342. }
  343. // standardEncryptionVerifier extract ECMA-376 standard encryption verifier.
  344. func standardEncryptionVerifier(algorithm string, blob []byte) StandardEncryptionVerifier {
  345. verifier := StandardEncryptionVerifier{
  346. SaltSize: binary.LittleEndian.Uint32(blob[:4]),
  347. Salt: blob[4:20],
  348. EncryptedVerifier: blob[20:36],
  349. VerifierHashSize: binary.LittleEndian.Uint32(blob[36:40]),
  350. }
  351. if algorithm == "RC4" {
  352. verifier.EncryptedVerifierHash = blob[40:60]
  353. } else if algorithm == "AES" {
  354. verifier.EncryptedVerifierHash = blob[40:72]
  355. }
  356. return verifier
  357. }
  358. // standardConvertPasswdToKey generate intermediate key from given password.
  359. func standardConvertPasswdToKey(header StandardEncryptionHeader, verifier StandardEncryptionVerifier, opt *Options) ([]byte, error) {
  360. encoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
  361. passwordBuffer, err := encoder.Bytes([]byte(opt.Password))
  362. if err != nil {
  363. return nil, err
  364. }
  365. key := hashing("sha1", verifier.Salt, passwordBuffer)
  366. for i := 0; i < iterCount; i++ {
  367. iterator := createUInt32LEBuffer(i, 4)
  368. key = hashing("sha1", iterator, key)
  369. }
  370. var block int
  371. hfinal := hashing("sha1", key, createUInt32LEBuffer(block, 4))
  372. cbRequiredKeyLength := int(header.KeySize) / 8
  373. cbHash := sha1.Size
  374. buf1 := bytes.Repeat([]byte{0x36}, 64)
  375. buf1 = append(standardXORBytes(hfinal, buf1[:cbHash]), buf1[cbHash:]...)
  376. x1 := hashing("sha1", buf1)
  377. buf2 := bytes.Repeat([]byte{0x5c}, 64)
  378. buf2 = append(standardXORBytes(hfinal, buf2[:cbHash]), buf2[cbHash:]...)
  379. x2 := hashing("sha1", buf2)
  380. x3 := append(x1, x2...)
  381. keyDerived := x3[:cbRequiredKeyLength]
  382. return keyDerived, err
  383. }
  384. // standardXORBytes perform XOR operations for two bytes slice.
  385. func standardXORBytes(a, b []byte) []byte {
  386. r := make([][2]byte, len(a), len(a))
  387. for i, e := range a {
  388. r[i] = [2]byte{e, b[i]}
  389. }
  390. buf := make([]byte, len(a))
  391. for p, q := range r {
  392. buf[p] = q[0] ^ q[1]
  393. }
  394. return buf
  395. }
  396. // ECMA-376 Agile Encryption
  397. // agileDecrypt decrypt the CFB file format with ECMA-376 agile encryption.
  398. // Support cryptographic algorithm: MD4, MD5, RIPEMD-160, SHA1, SHA256, SHA384 and SHA512.
  399. func agileDecrypt(encryptionInfoBuf, encryptedPackageBuf []byte, opt *Options) (packageBuf []byte, err error) {
  400. var encryptionInfo Encryption
  401. if encryptionInfo, err = parseEncryptionInfo(encryptionInfoBuf[8:]); err != nil {
  402. return
  403. }
  404. // Convert the password into an encryption key.
  405. key, err := convertPasswdToKey(opt.Password, blockKey, encryptionInfo)
  406. if err != nil {
  407. return
  408. }
  409. // Use the key to decrypt the package key.
  410. encryptedKey := encryptionInfo.KeyEncryptors.KeyEncryptor[0].EncryptedKey
  411. saltValue, err := base64.StdEncoding.DecodeString(encryptedKey.SaltValue)
  412. if err != nil {
  413. return
  414. }
  415. encryptedKeyValue, err := base64.StdEncoding.DecodeString(encryptedKey.EncryptedKeyValue)
  416. if err != nil {
  417. return
  418. }
  419. packageKey, err := crypt(false, encryptedKey.CipherAlgorithm, encryptedKey.CipherChaining, key, saltValue, encryptedKeyValue)
  420. // Use the package key to decrypt the package.
  421. return cryptPackage(false, packageKey, encryptedPackageBuf, encryptionInfo)
  422. }
  423. // convertPasswdToKey convert the password into an encryption key.
  424. func convertPasswdToKey(passwd string, blockKey []byte, encryption Encryption) (key []byte, err error) {
  425. var b bytes.Buffer
  426. saltValue, err := base64.StdEncoding.DecodeString(encryption.KeyEncryptors.KeyEncryptor[0].EncryptedKey.SaltValue)
  427. if err != nil {
  428. return
  429. }
  430. b.Write(saltValue)
  431. encoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
  432. passwordBuffer, err := encoder.Bytes([]byte(passwd))
  433. if err != nil {
  434. return
  435. }
  436. b.Write(passwordBuffer)
  437. // Generate the initial hash.
  438. key = hashing(encryption.KeyData.HashAlgorithm, b.Bytes())
  439. // Now regenerate until spin count.
  440. for i := 0; i < encryption.KeyEncryptors.KeyEncryptor[0].EncryptedKey.SpinCount; i++ {
  441. iterator := createUInt32LEBuffer(i, 4)
  442. key = hashing(encryption.KeyData.HashAlgorithm, iterator, key)
  443. }
  444. // Now generate the final hash.
  445. key = hashing(encryption.KeyData.HashAlgorithm, key, blockKey)
  446. // Truncate or pad as needed to get to length of keyBits.
  447. keyBytes := encryption.KeyEncryptors.KeyEncryptor[0].EncryptedKey.KeyBits / 8
  448. if len(key) < keyBytes {
  449. tmp := make([]byte, 0x36)
  450. key = append(key, tmp...)
  451. key = tmp
  452. } else if len(key) > keyBytes {
  453. key = key[:keyBytes]
  454. }
  455. return
  456. }
  457. // hashing data by specified hash algorithm.
  458. func hashing(hashAlgorithm string, buffer ...[]byte) (key []byte) {
  459. var hashMap = map[string]hash.Hash{
  460. "md4": md4.New(),
  461. "md5": md5.New(),
  462. "ripemd-160": ripemd160.New(),
  463. "sha1": sha1.New(),
  464. "sha256": sha256.New(),
  465. "sha384": sha512.New384(),
  466. "sha512": sha512.New(),
  467. }
  468. handler, ok := hashMap[strings.ToLower(hashAlgorithm)]
  469. if !ok {
  470. return key
  471. }
  472. for _, buf := range buffer {
  473. handler.Write(buf)
  474. }
  475. key = handler.Sum(nil)
  476. return key
  477. }
  478. // createUInt32LEBuffer create buffer with little endian 32-bit unsigned
  479. // integer.
  480. func createUInt32LEBuffer(value int, bufferSize int) []byte {
  481. buf := make([]byte, bufferSize)
  482. binary.LittleEndian.PutUint32(buf, uint32(value))
  483. return buf
  484. }
  485. // parseEncryptionInfo parse the encryption info XML into an object.
  486. func parseEncryptionInfo(encryptionInfo []byte) (encryption Encryption, err error) {
  487. err = xml.Unmarshal(encryptionInfo, &encryption)
  488. return
  489. }
  490. // crypt encrypt / decrypt input by given cipher algorithm, cipher chaining,
  491. // key and initialization vector.
  492. func crypt(encrypt bool, cipherAlgorithm, cipherChaining string, key, iv, input []byte) (packageKey []byte, err error) {
  493. block, err := aes.NewCipher(key)
  494. if err != nil {
  495. return input, err
  496. }
  497. var stream cipher.BlockMode
  498. if encrypt {
  499. stream = cipher.NewCBCEncrypter(block, iv)
  500. } else {
  501. stream = cipher.NewCBCDecrypter(block, iv)
  502. }
  503. stream.CryptBlocks(input, input)
  504. return input, nil
  505. }
  506. // cryptPackage encrypt / decrypt package by given packageKey and encryption
  507. // info.
  508. func cryptPackage(encrypt bool, packageKey, input []byte, encryption Encryption) (outputChunks []byte, err error) {
  509. encryptedKey := encryption.KeyData
  510. var offset = packageOffset
  511. if encrypt {
  512. offset = 0
  513. }
  514. var i, start, end int
  515. var iv, outputChunk []byte
  516. for end < len(input) {
  517. start = end
  518. end = start + packageEncryptionChunkSize
  519. if end > len(input) {
  520. end = len(input)
  521. }
  522. // Grab the next chunk
  523. var inputChunk []byte
  524. if (end + offset) < len(input) {
  525. inputChunk = input[start+offset : end+offset]
  526. } else {
  527. inputChunk = input[start+offset : end]
  528. }
  529. // Pad the chunk if it is not an integer multiple of the block size
  530. remainder := len(inputChunk) % encryptedKey.BlockSize
  531. if remainder != 0 {
  532. inputChunk = append(inputChunk, make([]byte, encryptedKey.BlockSize-remainder)...)
  533. }
  534. // Create the initialization vector
  535. iv, err = createIV(i, encryption)
  536. if err != nil {
  537. return
  538. }
  539. // Encrypt/decrypt the chunk and add it to the array
  540. outputChunk, err = crypt(encrypt, encryptedKey.CipherAlgorithm, encryptedKey.CipherChaining, packageKey, iv, inputChunk)
  541. if err != nil {
  542. return
  543. }
  544. outputChunks = append(outputChunks, outputChunk...)
  545. i++
  546. }
  547. if encrypt {
  548. outputChunks = append(createUInt32LEBuffer(len(input), 8), outputChunks...)
  549. }
  550. return
  551. }
  552. // createIV create an initialization vector (IV).
  553. func createIV(blockKey interface{}, encryption Encryption) ([]byte, error) {
  554. encryptedKey := encryption.KeyData
  555. // Create the block key from the current index
  556. var blockKeyBuf []byte
  557. if reflect.TypeOf(blockKey).Kind() == reflect.Int {
  558. blockKeyBuf = createUInt32LEBuffer(blockKey.(int), 4)
  559. } else {
  560. blockKeyBuf = blockKey.([]byte)
  561. }
  562. saltValue, err := base64.StdEncoding.DecodeString(encryptedKey.SaltValue)
  563. if err != nil {
  564. return nil, err
  565. }
  566. // Create the initialization vector by hashing the salt with the block key.
  567. // Truncate or pad as needed to meet the block size.
  568. iv := hashing(encryptedKey.HashAlgorithm, append(saltValue, blockKeyBuf...))
  569. if len(iv) < encryptedKey.BlockSize {
  570. tmp := make([]byte, 0x36)
  571. iv = append(iv, tmp...)
  572. iv = tmp
  573. } else if len(iv) > encryptedKey.BlockSize {
  574. iv = iv[0:encryptedKey.BlockSize]
  575. }
  576. return iv, nil
  577. }
  578. // randomBytes returns securely generated random bytes. It will return an error if the system's
  579. // secure random number generator fails to function correctly, in which case the caller should not
  580. // continue.
  581. func randomBytes(n int) ([]byte, error) {
  582. b := make([]byte, n)
  583. _, err := rand.Read(b)
  584. return b, err
  585. }