crypt.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  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/md5"
  15. "crypto/sha1"
  16. "crypto/sha256"
  17. "crypto/sha512"
  18. "encoding/base64"
  19. "encoding/binary"
  20. "encoding/xml"
  21. "errors"
  22. "hash"
  23. "strings"
  24. "github.com/richardlehane/mscfb"
  25. "golang.org/x/crypto/md4"
  26. "golang.org/x/crypto/ripemd160"
  27. "golang.org/x/text/encoding/unicode"
  28. )
  29. var (
  30. blockKey = []byte{0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6} // Block keys used for encryption
  31. packageOffset = 8 // First 8 bytes are the size of the stream
  32. packageEncryptionChunkSize = 4096
  33. iterCount = 50000
  34. cryptoIdentifier = []byte{ // checking protect workbook by [MS-OFFCRYPTO] - v20181211 3.1 FeatureIdentifier
  35. 0x3c, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00,
  36. 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00,
  37. 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x2e, 0x00, 0x44, 0x00, 0x61, 0x00,
  38. 0x74, 0x00, 0x61, 0x00, 0x53, 0x00, 0x70, 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00,
  39. 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  40. }
  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. 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 = errors.New("unsupport encryption mechanism")
  135. break
  136. }
  137. return
  138. }
  139. // extractPart extract data from storage by specified part name.
  140. func extractPart(doc *mscfb.Reader) (encryptionInfoBuf, encryptedPackageBuf []byte) {
  141. for entry, err := doc.Next(); err == nil; entry, err = doc.Next() {
  142. switch entry.Name {
  143. case "EncryptionInfo":
  144. buf := make([]byte, entry.Size)
  145. i, _ := doc.Read(buf)
  146. if i > 0 {
  147. encryptionInfoBuf = buf
  148. break
  149. }
  150. case "EncryptedPackage":
  151. buf := make([]byte, entry.Size)
  152. i, _ := doc.Read(buf)
  153. if i > 0 {
  154. encryptedPackageBuf = buf
  155. break
  156. }
  157. }
  158. }
  159. return
  160. }
  161. // encryptionMechanism parse password-protected documents created mechanism.
  162. func encryptionMechanism(buffer []byte) (mechanism string, err error) {
  163. if len(buffer) < 4 {
  164. err = errors.New("unknown encryption mechanism")
  165. return
  166. }
  167. versionMajor, versionMinor := binary.LittleEndian.Uint16(buffer[0:2]), binary.LittleEndian.Uint16(buffer[2:4])
  168. if versionMajor == 4 && versionMinor == 4 {
  169. mechanism = "agile"
  170. return
  171. } else if (2 <= versionMajor && versionMajor <= 4) && versionMinor == 2 {
  172. mechanism = "standard"
  173. return
  174. } else if (versionMajor == 3 || versionMajor == 4) && versionMinor == 3 {
  175. mechanism = "extensible"
  176. }
  177. err = errors.New("unsupport encryption mechanism")
  178. return
  179. }
  180. // ECMA-376 Standard Encryption
  181. // standardDecrypt decrypt the CFB file format with ECMA-376 standard encryption.
  182. func standardDecrypt(encryptionInfoBuf, encryptedPackageBuf []byte, opt *Options) ([]byte, error) {
  183. encryptionHeaderSize := binary.LittleEndian.Uint32(encryptionInfoBuf[8:12])
  184. block := encryptionInfoBuf[12 : 12+encryptionHeaderSize]
  185. header := StandardEncryptionHeader{
  186. Flags: binary.LittleEndian.Uint32(block[:4]),
  187. SizeExtra: binary.LittleEndian.Uint32(block[4:8]),
  188. AlgID: binary.LittleEndian.Uint32(block[8:12]),
  189. AlgIDHash: binary.LittleEndian.Uint32(block[12:16]),
  190. KeySize: binary.LittleEndian.Uint32(block[16:20]),
  191. ProviderType: binary.LittleEndian.Uint32(block[20:24]),
  192. Reserved1: binary.LittleEndian.Uint32(block[24:28]),
  193. Reserved2: binary.LittleEndian.Uint32(block[28:32]),
  194. CspName: string(block[32:]),
  195. }
  196. block = encryptionInfoBuf[12+encryptionHeaderSize:]
  197. algIDMap := map[uint32]string{
  198. 0x0000660E: "AES-128",
  199. 0x0000660F: "AES-192",
  200. 0x00006610: "AES-256",
  201. }
  202. algorithm := "AES"
  203. _, ok := algIDMap[header.AlgID]
  204. if !ok {
  205. algorithm = "RC4"
  206. }
  207. verifier := standardEncryptionVerifier(algorithm, block)
  208. secretKey, err := standardConvertPasswdToKey(header, verifier, opt)
  209. if err != nil {
  210. return nil, err
  211. }
  212. // decrypted data
  213. x := encryptedPackageBuf[8:]
  214. blob, err := aes.NewCipher(secretKey)
  215. if err != nil {
  216. return nil, err
  217. }
  218. decrypted := make([]byte, len(x))
  219. size := 16
  220. for bs, be := 0, size; bs < len(x); bs, be = bs+size, be+size {
  221. blob.Decrypt(decrypted[bs:be], x[bs:be])
  222. }
  223. return decrypted, err
  224. }
  225. // standardEncryptionVerifier extract ECMA-376 standard encryption verifier.
  226. func standardEncryptionVerifier(algorithm string, blob []byte) StandardEncryptionVerifier {
  227. verifier := StandardEncryptionVerifier{
  228. SaltSize: binary.LittleEndian.Uint32(blob[:4]),
  229. Salt: blob[4:20],
  230. EncryptedVerifier: blob[20:36],
  231. VerifierHashSize: binary.LittleEndian.Uint32(blob[36:40]),
  232. }
  233. if algorithm == "RC4" {
  234. verifier.EncryptedVerifierHash = blob[40:60]
  235. } else if algorithm == "AES" {
  236. verifier.EncryptedVerifierHash = blob[40:72]
  237. }
  238. return verifier
  239. }
  240. // standardConvertPasswdToKey generate intermediate key from given password.
  241. func standardConvertPasswdToKey(header StandardEncryptionHeader, verifier StandardEncryptionVerifier, opt *Options) ([]byte, error) {
  242. encoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
  243. passwordBuffer, err := encoder.Bytes([]byte(opt.Password))
  244. if err != nil {
  245. return nil, err
  246. }
  247. key := hashing("sha1", verifier.Salt, passwordBuffer)
  248. for i := 0; i < iterCount; i++ {
  249. iterator := createUInt32LEBuffer(i)
  250. key = hashing("sha1", iterator, key)
  251. }
  252. var block int
  253. hfinal := hashing("sha1", key, createUInt32LEBuffer(block))
  254. cbRequiredKeyLength := int(header.KeySize) / 8
  255. cbHash := sha1.Size
  256. buf1 := bytes.Repeat([]byte{0x36}, 64)
  257. buf1 = append(standardXORBytes(hfinal, buf1[:cbHash]), buf1[cbHash:]...)
  258. x1 := hashing("sha1", buf1)
  259. buf2 := bytes.Repeat([]byte{0x5c}, 64)
  260. buf2 = append(standardXORBytes(hfinal, buf2[:cbHash]), buf2[cbHash:]...)
  261. x2 := hashing("sha1", buf2)
  262. x3 := append(x1, x2...)
  263. keyDerived := x3[:cbRequiredKeyLength]
  264. return keyDerived, err
  265. }
  266. // standardXORBytes perform XOR operations for two bytes slice.
  267. func standardXORBytes(a, b []byte) []byte {
  268. r := make([][2]byte, len(a), len(a))
  269. for i, e := range a {
  270. r[i] = [2]byte{e, b[i]}
  271. }
  272. buf := make([]byte, len(a))
  273. for p, q := range r {
  274. buf[p] = q[0] ^ q[1]
  275. }
  276. return buf
  277. }
  278. // ECMA-376 Agile Encryption
  279. // agileDecrypt decrypt the CFB file format with ECMA-376 agile encryption.
  280. // Support cryptographic algorithm: MD4, MD5, RIPEMD-160, SHA1, SHA256, SHA384
  281. // and SHA512.
  282. func agileDecrypt(encryptionInfoBuf, encryptedPackageBuf []byte, opt *Options) (packageBuf []byte, err error) {
  283. var encryptionInfo Encryption
  284. if encryptionInfo, err = parseEncryptionInfo(encryptionInfoBuf[8:]); err != nil {
  285. return
  286. }
  287. // Convert the password into an encryption key.
  288. key, err := convertPasswdToKey(opt.Password, encryptionInfo)
  289. if err != nil {
  290. return
  291. }
  292. // Use the key to decrypt the package key.
  293. encryptedKey := encryptionInfo.KeyEncryptors.KeyEncryptor[0].EncryptedKey
  294. saltValue, err := base64.StdEncoding.DecodeString(encryptedKey.SaltValue)
  295. if err != nil {
  296. return
  297. }
  298. encryptedKeyValue, err := base64.StdEncoding.DecodeString(encryptedKey.EncryptedKeyValue)
  299. if err != nil {
  300. return
  301. }
  302. packageKey, err := crypt(false, encryptedKey.CipherAlgorithm, encryptedKey.CipherChaining, key, saltValue, encryptedKeyValue)
  303. // Use the package key to decrypt the package.
  304. return cryptPackage(false, packageKey, encryptedPackageBuf, encryptionInfo)
  305. }
  306. // convertPasswdToKey convert the password into an encryption key.
  307. func convertPasswdToKey(passwd string, encryption Encryption) (key []byte, err error) {
  308. var b bytes.Buffer
  309. saltValue, err := base64.StdEncoding.DecodeString(encryption.KeyEncryptors.KeyEncryptor[0].EncryptedKey.SaltValue)
  310. if err != nil {
  311. return
  312. }
  313. b.Write(saltValue)
  314. encoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
  315. passwordBuffer, err := encoder.Bytes([]byte(passwd))
  316. if err != nil {
  317. return
  318. }
  319. b.Write(passwordBuffer)
  320. // Generate the initial hash.
  321. key = hashing(encryption.KeyData.HashAlgorithm, b.Bytes())
  322. // Now regenerate until spin count.
  323. for i := 0; i < encryption.KeyEncryptors.KeyEncryptor[0].EncryptedKey.SpinCount; i++ {
  324. iterator := createUInt32LEBuffer(i)
  325. key = hashing(encryption.KeyData.HashAlgorithm, iterator, key)
  326. }
  327. // Now generate the final hash.
  328. key = hashing(encryption.KeyData.HashAlgorithm, key, blockKey)
  329. // Truncate or pad as needed to get to length of keyBits.
  330. keyBytes := encryption.KeyEncryptors.KeyEncryptor[0].EncryptedKey.KeyBits / 8
  331. if len(key) < keyBytes {
  332. tmp := make([]byte, 0x36)
  333. key = append(key, tmp...)
  334. key = tmp
  335. } else if len(key) > keyBytes {
  336. key = key[:keyBytes]
  337. }
  338. return
  339. }
  340. // hashing data by specified hash algorithm.
  341. func hashing(hashAlgorithm string, buffer ...[]byte) (key []byte) {
  342. var hashMap = map[string]hash.Hash{
  343. "md4": md4.New(),
  344. "md5": md5.New(),
  345. "ripemd-160": ripemd160.New(),
  346. "sha1": sha1.New(),
  347. "sha256": sha256.New(),
  348. "sha384": sha512.New384(),
  349. "sha512": sha512.New(),
  350. }
  351. handler, ok := hashMap[strings.ToLower(hashAlgorithm)]
  352. if !ok {
  353. return key
  354. }
  355. for _, buf := range buffer {
  356. handler.Write(buf)
  357. }
  358. key = handler.Sum(nil)
  359. return key
  360. }
  361. // createUInt32LEBuffer create buffer with little endian 32-bit unsigned
  362. // integer.
  363. func createUInt32LEBuffer(value int) []byte {
  364. buf := make([]byte, 4)
  365. binary.LittleEndian.PutUint32(buf, uint32(value))
  366. return buf
  367. }
  368. // parseEncryptionInfo parse the encryption info XML into an object.
  369. func parseEncryptionInfo(encryptionInfo []byte) (encryption Encryption, err error) {
  370. err = xml.Unmarshal(encryptionInfo, &encryption)
  371. return
  372. }
  373. // crypt encrypt / decrypt input by given cipher algorithm, cipher chaining,
  374. // key and initialization vector.
  375. func crypt(encrypt bool, cipherAlgorithm, cipherChaining string, key, iv, input []byte) (packageKey []byte, err error) {
  376. block, err := aes.NewCipher(key)
  377. if err != nil {
  378. return input, err
  379. }
  380. stream := cipher.NewCBCDecrypter(block, iv)
  381. stream.CryptBlocks(input, input)
  382. return input, nil
  383. }
  384. // cryptPackage encrypt / decrypt package by given packageKey and encryption
  385. // info.
  386. func cryptPackage(encrypt bool, packageKey, input []byte, encryption Encryption) (outputChunks []byte, err error) {
  387. encryptedKey := encryption.KeyData
  388. var offset = packageOffset
  389. if encrypt {
  390. offset = 0
  391. }
  392. var i, start, end int
  393. var iv, outputChunk []byte
  394. for end < len(input) {
  395. start = end
  396. end = start + packageEncryptionChunkSize
  397. if end > len(input) {
  398. end = len(input)
  399. }
  400. // Grab the next chunk
  401. var inputChunk []byte
  402. if (end + offset) < len(input) {
  403. inputChunk = input[start+offset : end+offset]
  404. } else {
  405. inputChunk = input[start+offset : end]
  406. }
  407. // Pad the chunk if it is not an integer multiple of the block size
  408. remainder := len(inputChunk) % encryptedKey.BlockSize
  409. if remainder != 0 {
  410. inputChunk = append(inputChunk, make([]byte, encryptedKey.BlockSize-remainder)...)
  411. }
  412. // Create the initialization vector
  413. iv, err = createIV(encrypt, i, encryption)
  414. if err != nil {
  415. return
  416. }
  417. // Encrypt/decrypt the chunk and add it to the array
  418. outputChunk, err = crypt(encrypt, encryptedKey.CipherAlgorithm, encryptedKey.CipherChaining, packageKey, iv, inputChunk)
  419. if err != nil {
  420. return
  421. }
  422. outputChunks = append(outputChunks, outputChunk...)
  423. i++
  424. }
  425. return
  426. }
  427. // createIV create an initialization vector (IV).
  428. func createIV(encrypt bool, blockKey int, encryption Encryption) ([]byte, error) {
  429. encryptedKey := encryption.KeyData
  430. // Create the block key from the current index
  431. blockKeyBuf := createUInt32LEBuffer(blockKey)
  432. var b bytes.Buffer
  433. saltValue, err := base64.StdEncoding.DecodeString(encryptedKey.SaltValue)
  434. if err != nil {
  435. return nil, err
  436. }
  437. b.Write(saltValue)
  438. b.Write(blockKeyBuf)
  439. // Create the initialization vector by hashing the salt with the block key.
  440. // Truncate or pad as needed to meet the block size.
  441. iv := hashing(encryptedKey.HashAlgorithm, b.Bytes())
  442. if len(iv) < encryptedKey.BlockSize {
  443. tmp := make([]byte, 0x36)
  444. iv = append(iv, tmp...)
  445. iv = tmp
  446. } else if len(iv) > encryptedKey.BlockSize {
  447. iv = iv[0:encryptedKey.BlockSize]
  448. }
  449. return iv, nil
  450. }