3.1.7.1.5 Encrypting the Message Body

If the PrivacyLevel ADM attribute of the Message ([MS-MQDMPR] section 3.1.1.12) ADM element is not None, the message body MUST be encrypted. To encrypt the message, the protocol MUST follow these steps:

  • If the UserMessage.UserHeader.DestinationQueue field does not contain a public format name ([MS-MQMQ] section 2.1.3) or a private format name ([MS-MQMQ] section 2.1.4), the protocol MUST perform the steps in section 3.1.7.1.5.1.

  • If the RemoteQMPublicKey ADM element is not initialized, the protocol MUST initialize it according to the following steps:

    • Raise a Read Directory ([MS-MQDMPR] section 3.1.7.1.20) event with the following arguments:

      • iDirectoryObjectType = "QueueManager"

      • iFilter = an array of attribute-filter expressions that contains one element: "Identifier" EQUALS RemoteQMGuid

      • iAttributeList = an array of strings that contains one element: "PublicEncryptionKeyList"

    • If the return result rStatus of the Read Directory event is not DirectoryOperationResult.Success, perform the steps in section 3.1.7.1.5.1.

    • The MQDSPUBLICKEYS ([MS-MQMQ] section 2.2.2) structure in the RemoteQMPublicKey ADM element SHOULD<65> contain three MQDSPUBLICKEY  ([MS-MQMQ] section 2.2.1) structures, with sProviderName field values of "Microsoft Base Cryptographic Provider v1.0", "Microsoft Enhanced Cryptographic Provider v1.0", and "Microsoft Enhanced RSA and AES Cryptographic Provider" and aBuf.bitlen field values of 512, 1024, and 1024, respectively. These keys are generated for use with the RSA key exchange algorithm ([RFC8017]).

  • Let UseCSP be a 16-bit null-terminated Unicode string representing the cryptography service provider (CSP) to be used to encrypt the message, UseAlgorithm be a 32-bit unsigned integer representing the encryption algorithm to be used, UseSymmKeyLength be a 32-bit unsigned integer representing the length in bits of the symmetric key to be used, and UsePublicKey be a PUBLICKEYBLOB (section 2.4.1). The protocol SHOULD<66> select a CSP, encryption algorithm, and key length and set the values of UseCSP, UseAlgorithm, and UseSymmKeyLength according to the following steps:

    • If the MQDSPUBLICKEYS structure in the RemoteQMPublicKey ADM element contains an MQDSPUBLICKEY structure where the sProviderName field is "Microsoft Enhanced RSA and AES Cryptographic Provider", set UseCSP to "Microsoft Enhanced RSA and AES Cryptographic Provider"; set UseAlgorithm to the value of PreferredAdvancedAlgorithm; set UseSymmKeyLength according to the value of PreferredAdvancedAlgorithm using the following table; and set UsePublicKey to the PUBLICKEYBLOB (section 2.4.1) that results when the abuf field of the MQDSPUBLICKEY structure is processed according to the steps in section 3.1.7.1.5.2. If Message.PrivacyLevel is Advanced and there is no such MQDSPUBLICKEY structure, then perform the steps in section 3.1.7.1.5.1.

      PreferredAdvancedAlgorithm

      UseSymmKeyLength

      0x00006610

      256

      0x0000660E

      128

      0x0000660F

      192

    • If UseCSP was not set in the preceding step and the MQDSPUBLICKEYS structure in the RemoteQMPublicKey ADM element contains an MQDSPUBLICKEY structure where the sProviderName field is "Microsoft Enhanced Cryptographic Provider v1.0", set UseCSP to "Microsoft Enhanced Cryptographic Provider v1.0"; set UseSymmKeyLength to 128; set UseAlgorithm to the value of PreferredEnhancedAlgorithm; and set UsePublicKey to the PUBLICKEYBLOB (section 2.4.1) that results when the abuf field of the MQDSPUBLICKEY structure is processed according to the steps in section 3.1.7.1.5.2. If PreferredEnhancedAlgorithm is 0x00006602 and SendEnhancedRC2Using40BitKeys is TRUE, set UseSymmKeyLength to 40. If Message.PrivacyLevel is Enhanced and there is no such MQDSPUBLICKEY structure, then perform the steps in section 3.1.7.1.5.1.

    • If UseCSP was not set in the preceding steps, and the MQDSPUBLICKEYS structure in the RemoteQMPublicKey ADM element contains an MQDSPUBLICKEY structure where the sProviderName field is "Microsoft Base Cryptographic Provider v1.0", set UseCSP to "Microsoft Base Cryptographic Provider v1.0"; set UseSymmKeyLength to 40; set UseAlgorithm to the value of PreferredBaseAlgorithm; and set UsePublicKey to the PUBLICKEYBLOB (section 2.4.1) that results when the abuf field of the MQDSPUBLICKEY structure is processed according to the steps in section 3.1.7.1.5.2.

    • If UseCSP has not been set in the preceding steps, perform the steps in section 3.1.7.1.5.1.

  • The protocol SHOULD<67> search the SendSymmetricKeyCache ADM element for a CachedSymmetricKey (section 3.1.1.3.3) ADM element instance where CachedSymmetricKey.CryptoServiceProvider is the same as UseCSP, CachedSymmetricKey.CryptoAlgorithm is the same as UseAlgorithm, and CachedSymmetricKey.RemoteQMGuid is the same as the RemoteQMGuid ADM element. If found, let UseCachedKey be a reference to the matching CachedSymmetricKey ADM element instance. If one is not found, the protocol MUST perform the following steps:

    • Create a new CachedSymmetricKey ADM element instance rCachedSymmetricKey and initialize it as follows:

      • rCachedSymmetricKey.RemoteQMGuid is set to the value of the RemoteQMGuid session Abstract Data Model (ADM) element.

      • rCachedSymmetricKey.CryptoServiceProvider is set to the value of UseCSP.

      • rCachedSymmetricKey.CryptoAlgorithm is set to the value of UseAlgorithm.

      • rCachedSymmetricKey.SymmetricKey is a session symmetric key generated for use with the algorithm indicated by UseAlgorithm according to the following table and of length in bits indicated by UseSymmKeyLength. If UseCSP is "Microsoft Enhanced Cryptographic Provider v1.0" and UseAlgorithm is 0x00006602 and UseSymmKeyLength is 40, then the 40-bit key generated MUST be padded with 88 zero bits for a total of 128 bits.

        UseAlgorithm value

        Algorithm

        0x0000660e, 0x0000660f, 0x00006610

        AES [FIPS197]

        0x00006602

        RC2 [RFC2268]

        0x00006801

        RC4 [RFC4757]

      • rCachedSymmetricKey.EncryptedSymmetricKey is set to a SIMPLEBLOB (section 2.4.2) containing the session symmetric key encrypted by the RSA key exchange algorithm ([RFC8017]) using the public key in UsePublicKey.

      • rCachedSymmetricKey.CachedTime is set to the current date and time.

    • The newly created CachedSymmetricKey ADM element instance rCachedSymmetricKey SHOULD<68> be added to the SendSymmetricKeyCache ADM element. If doing so would cause the number of entries in the list to exceed the value of the SendSymmetricKeyCacheSize ADM element, then the protocol MUST create space in the list by sorting the entries by the CachedTime ADM attribute values and discarding the (SendSymmetricKeyCacheSize / 2) entries that are oldest.

    • The protocol SHOULD<69> start the SendSymmetricKeyCache Cleanup Timer (section 3.1.2.11) with a duration of the value of the SymmetricKeyShortLifetime ADM element in milliseconds if it is not already running.

    • UseCachedKey MUST be set to refer to the newly created CachedSymmetricKey ADM element instance rCachedSymmetricKey.

  • Encrypt the MessagePropertiesHeader.MessageBody field according to the method specified in the normative reference for the algorithm indicated by UseAlgorithm, using the key in UseCachedKey.SymmetricKey, and place the encrypted data in the MessagePropertiesHeader.MessageBody field. For AES encryption, the AES algorithm described in [FIPS197] is employed in Cipher Block Chaining (CBC) mode [SP800-38A] with a zero Initial Value (IV). The size of the MessagePropertiesHeader.MessageBody field MUST be adjusted if the encrypted data is a different size than the original data, and the MessagePropertiesHeader.AllocationBodySize field MUST be set to the size of the encrypted data. If the encryption fails, perform the steps in section 3.1.7.1.5.1.

  • The MessagePropertiesHeader.EncryptionAlgorithm field MUST be set to the value of UseAlgorithm.

  • The SecurityHeader.ProviderName field MUST be set to the value of UseCSP, and the SecurityHeader.ProviderNameSize field MUST be set to the size, in bytes, of the ProviderName field.

  • The SecurityHeader.EncryptionKey field MUST be set to the contents of UseCachedKey.EncryptedSymmetricKey, and the SecurityHeader.EncryptionKeySize field MUST be set to the size, in bytes, of UseCachedKey.EncryptedSymmetricKey.