crypt.go 21 KB

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