crypt.go 21 KB

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