nopSolutions/nopCommerce · error · NopException

Admin.Configuration.Settings.GeneralCommon.EncryptionKey.Too

Error message

Admin.Configuration.Settings.GeneralCommon.EncryptionKey.TooShort

What it means

Thrown by ChangeEncryptionKey (POST) when the supplied EncryptionKey is null/empty or not exactly 16 characters. nopCommerce requires a 16-char encryption key for its symmetric encryption; the message is a localized resource key resolved before throwing as NopException. This guards a destructive key-rotation operation.

Source

Thrown at src/Presentation/Nop.Web/Areas/Admin/Controllers/SettingController.cs:1779

        return View(model);
    }

    [HttpPost, ActionName("GeneralCommon")]
    [FormValueRequired("changeencryptionkey")]
    [CheckPermission(StandardPermission.Configuration.MANAGE_SETTINGS)]
    public virtual async Task<IActionResult> ChangeEncryptionKey(GeneralCommonSettingsModel model)
    {
        var storeScope = await _storeContext.GetActiveStoreScopeConfigurationAsync();
        var securitySettings = await _settingService.LoadSettingAsync<SecuritySettings>(storeScope);

        try
        {
            if (model.SecuritySettings.EncryptionKey == null)
                model.SecuritySettings.EncryptionKey = string.Empty;

            var newEncryptionPrivateKey = model.SecuritySettings.EncryptionKey;
            if (string.IsNullOrEmpty(newEncryptionPrivateKey) || newEncryptionPrivateKey.Length != 16)
                throw new NopException(await _localizationService.GetResourceAsync("Admin.Configuration.Settings.GeneralCommon.EncryptionKey.TooShort"));

            var oldEncryptionPrivateKey = securitySettings.EncryptionKey;
            if (oldEncryptionPrivateKey == newEncryptionPrivateKey)
                throw new NopException(await _localizationService.GetResourceAsync("Admin.Configuration.Settings.GeneralCommon.EncryptionKey.TheSame"));

            //update password information
            //optimization - load only passwords with PasswordFormat.Encrypted
            var customerPasswords = await _customerService.GetCustomerPasswordsAsync(passwordFormat: PasswordFormat.Encrypted);
            foreach (var customerPassword in customerPasswords)
            {
                var decryptedPassword = _encryptionService.DecryptText(customerPassword.Password, oldEncryptionPrivateKey);
                var encryptedPassword = _encryptionService.EncryptText(decryptedPassword, newEncryptionPrivateKey);

                customerPassword.Password = encryptedPassword;
                await _customerService.UpdateCustomerPasswordAsync(customerPassword);
            }

            securitySettings.EncryptionKey = newEncryptionPrivateKey;

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Generate exactly 16 characters (mix of letters/digits/symbols) for the new key.
  2. Trim/validate the field client-side to enforce length 16 before submit.
  3. Use a cryptographically random 16-char string (e.g. from a password manager).
  4. Back up the old key before submitting; rotation re-encrypts all Encrypted-format passwords.

Example fix

// before
if (string.IsNullOrEmpty(newEncryptionPrivateKey) || newEncryptionPrivateKey.Length != 16)
    throw new NopException(await _localizationService.GetResourceAsync("Admin.Configuration.Settings.GeneralCommon.EncryptionKey.TooShort"));

// after (client-side guard)
<input asp-for="SecuritySettings.EncryptionKey" minlength="16" maxlength="16" required />
// and server-side, give a friendlier message:
if (string.IsNullOrEmpty(newEncryptionPrivateKey) || newEncryptionPrivateKey.Length != 16)
{
    _notificationService.ErrorNotification("Encryption key must be exactly 16 characters.");
    return View(model);
}
Defensive patterns

Strategy: validation

Validate before calling

var key = (model.SecuritySettings.EncryptionKey ?? string.Empty).Trim();
if (key.Length != 16)
    return ErrorResult("Encryption key must be exactly 16 characters.");

Type guard

static bool IsValidEncryptionKey(string key)
    => !string.IsNullOrWhiteSpace(key) && key.Trim().Length == 16;

Try / catch

catch (NopException ex) when (ex.Message.Contains("EncryptionKey.TooShort"))
{ _notificationService.ErrorNotification("Key must be 16 chars."); return View(model); }

Prevention

When it happens

Trigger: Submitting the encryption-key change form with an empty key, a short/long key, or whitespace; pasting a key of wrong length; browser autofill truncating the field.

Common situations: Operators generating keys with wrong entropy length; copy-paste errors; misunderstood requirement (assuming any string is fine); automated config pushes sending a non-16-char value.

Related errors


AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13). Data as JSON: /api/errors/d5fcf3b8c8ff2e16. Report an issue: GitHub.