dotnet/wpf · error · RightsManagementException

EncryptionNotPermitted

EncryptionNotPermitted

Error message

RightsManagementFailureCode.EncryptionNotPermitted

What it means

CryptoProvider.Encrypt throws RightsManagementException with failure code EncryptionNotPermitted when the CanEncrypt property is false. CanEncrypt reflects whether the rights-management license bound to this CryptoProvider grants the ENCRYPT grant; without it the underlying unmanaged DRM layer is not allowed to encrypt content.

Solutions

  1. Obtain a UseLicense/PublishLicense that grants the Encrypt right (e.g. via UnsignedPublishLicense with an OWNER or EDIT/ENCRYPT grant for the user)
  2. Check provider.CanEncrypt before calling Encrypt and branch accordingly
  3. Re-acquire the license from the rights server with the correct rights for this principal
  4. If decrypt-then-re-encrypt is intended, decrypt with Decrypt and create a new CryptoProvider from a license granting Encrypt

Example fix

// before
byte[] cipher = provider.Encrypt(clearText);
// after
if (!provider.CanEncrypt)
    throw new InvalidOperationException("License does not grant the Encrypt right.");
byte[] cipher = provider.Encrypt(clearText);
Defensive patterns

Strategy: validation

Validate before calling

if (!provider.CanEncrypt)
    throw new InvalidOperationException("Current license does not grant the Encrypt right.");

Type guard

bool CanEncryptSafely(CryptoProvider p) => p is { IsDisposed: false, CanEncrypt: true };

Try / catch

try { cipher = provider.Encrypt(clearText); }
catch (RightsManagementException rmEx) when (rmEx.FailureCode == RightsManagementFailureCode.EncryptionNotPermitted)
{ /* request upgraded license from rights server */ }

Prevention

When it happens

Trigger: Calling Encrypt on a CryptoProvider created from a UseLicense/signed PublishLicense whose bound grants do not include the Encrypt right (e.g. a consumer license with view-only rights).

Common situations: End user received a read-only protected document license; server issued a UseLicense without ENCRYPT; application assumed an owner-level CryptoProvider but got a consumer one.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/ff74bac7eca12fc8. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Security/RightsManagement/CryptoProvider.cs:61

        /// BlockSize property. BlockSize property should be used to determine the amount of extra 
        /// padding to be added to the clear text. The length, in bytes, of the buffer holding content to 
        /// be encrypted should be a multiple of the block cipher block size. 
        /// RMS system currently uses AES block cipher. All blocks are encrypted independently, so that 2 blocks 
        /// of identical clear text will produce identical results after encryption.  An application 
        /// is encouraged to either compress data prior to encryption or create some other scheme to mitigate 
        /// threats potentially arising from independent block encryption.
        /// </summary> 
        public byte[] Encrypt(byte[] clearText)
        {
            CheckDisposed();

            ArgumentNullException.ThrowIfNull(clearText);

            // validation of the proper size of the clearText is done by the unmanaged libraries 

            if (!CanEncrypt)
            {
                throw new RightsManagementException(RightsManagementFailureCode.EncryptionNotPermitted);
            }
            
            // first get the size
            uint outputBufferSize=0;
            byte[] outputBuffer = null;
            int hr;

#if DEBUG
            hr= SafeNativeMethods.DRMEncrypt(
                            EncryptorHandle, 
                            0, 
                            (uint)clearText.Length, 
                            clearText,
                            ref outputBufferSize,
                            null);

            Errors.ThrowOnErrorCode(hr);

View on GitHub (pinned to 81131a70a4)