# 2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption)

The encryption key for ECMA-376 document encryption [ECMA-376] MUST be generated by using the following method, which is derived from PKCS #5: Password-Based Cryptography Version 2.0 [RFC2898].

Let H() be a hashing algorithm as determined by the **EncryptionHeader.AlgIDHash**
field, H_{n} be the hash data of the n^{th} iteration, and a
plus sign (+) represent concatenation. This hashing algorithm MUST be SHA-1.
The password MUST be provided as an array of Unicode characters. Limitations on
the length of the password and the characters used by the password are
implementation-dependent. The initial password hash is generated as follows:

H

_{0}= H(salt + password)

The salt used MUST be generated randomly and MUST be 16
bytes in size. The salt MUST be stored in the **EncryptionVerifier.Salt**
field contained within the **\EncryptionInfo** stream (1) as
specified in section 2.3.4.5. The hash
is then iterated by using the following approach:

H

_{n}= H(iterator + H_{n-1})

where **iterator** is an unsigned 32-bit value that is
initially set to 0x00000000 and then incremented monotonically on each
iteration until 50,000 iterations have been performed. The value of **iterator**
on the last iteration MUST be 49,999.

After the final hash data has been obtained, the encryption
key MUST be generated by using the final hash data, and the block number MUST
be 0x00000000. The encryption algorithm MUST be specified in the **EncryptionHeader.AlgID**
field. The encryption algorithm MUST use ECB mode. The method
used to generate the hash data that is the input into the key derivation
algorithm is as follows:

H

_{final}= H(H_{n}+ block)

The encryption key derivation method is specified by the following steps:

Let

**cbRequiredKeyLength**be equal to the size, in bytes, of the required key length for the relevant encryption algorithm as specified by the**EncryptionHeader**structure. Note that**cbRequiredKeyLength**MUST be less than or equal to 40.Let

**cbHash**be the number of bytes output by the hashing algorithm H.Form a 64-byte buffer by repeating the constant 0x36 64 times. XOR H

_{final}into the first**cbHash**bytes of this buffer, and compute a hash of the resulting 64-byte buffer by using hashing algorithm H. This will yield a hash value of length**cbHash**. Let the resulting value be called**X1**.Form another 64-byte buffer by repeating the constant 0x5C 64 times. XOR H

_{final}into the first**cbHash**bytes of this buffer, and compute a hash of the resulting 64-byte buffer by using hash algorithm H. This yields a hash value of length**cbHash**. Let the resulting value be called**X2**.Concatenate

**X1**with**X2**to form**X3**, which will yield a value twice the length of**cbHash**.Let

**keyDerived**be equal to the first**cbRequiredKeyLength**bytes of**X3**.