2.3.5.2 RC4 CryptoAPI Encryption Key Generation

The encryption key for RC4 CryptoAPI binary document encryption MUST be generated by using the following approach.

Let H() be a hashing algorithm as determined by the EncryptionHeader.AlgIDHash field, and a plus sign (+) represents concatenation. 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. For details about behavior variations, see [MS-DOC], [MS-XLS], and [MS-PPT]. Unless otherwise specified, the maximum password length MUST be 255 Unicode characters.

The password hash is generated as follows:

  • H0 = 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 as specified in section 2.3.4.5. Note that the hash MUST NOT be iterated. See section 4 for additional notes.

After the hash has been obtained, the encryption key MUST be generated by using the hash data and a block number that is provided by the application. The encryption algorithm MUST be specified in the EncryptionHeader.AlgID field.

The method used to generate the hash data that is the input into the key derivation algorithm is as follows:

  • Hfinal = H(H0 + block)

The block number MUST be a 32-bit unsigned value provided by the application.

Let keyLength be the key length, in bits, as specified by the RC4 CryptoAPI Encryption Header KeySize field.

The first keyLength bits of Hfinal MUST be considered the derived encryption key, unless keyLength is exactly 40 bits long. An SHA-1 hash is 160 bits long, and the maximum RC4 key length is 128 bits; therefore, keyLength MUST be less than or equal to 128 bits. If keyLength is exactly 40 bits, the encryption key MUST be composed of the first 40 bits of Hfinal and 88 bits set to zero, creating a 128-bit key.