{"record":{"id":"d5fcf3b8c8ff2e16","repo":"nopSolutions/nopCommerce","slug":"admin-configuration-settings-generalcommon-encrypt","errorCode":null,"errorMessage":"Admin.Configuration.Settings.GeneralCommon.EncryptionKey.TooShort","messagePattern":"Admin\\.Configuration\\.Settings\\.GeneralCommon\\.EncryptionKey\\.TooShort","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Presentation/Nop.Web/Areas/Admin/Controllers/SettingController.cs","lineNumber":1779,"sourceCode":"        return View(model);\n    }\n\n    [HttpPost, ActionName(\"GeneralCommon\")]\n    [FormValueRequired(\"changeencryptionkey\")]\n    [CheckPermission(StandardPermission.Configuration.MANAGE_SETTINGS)]\n    public virtual async Task<IActionResult> ChangeEncryptionKey(GeneralCommonSettingsModel model)\n    {\n        var storeScope = await _storeContext.GetActiveStoreScopeConfigurationAsync();\n        var securitySettings = await _settingService.LoadSettingAsync<SecuritySettings>(storeScope);\n\n        try\n        {\n            if (model.SecuritySettings.EncryptionKey == null)\n                model.SecuritySettings.EncryptionKey = string.Empty;\n\n            var newEncryptionPrivateKey = model.SecuritySettings.EncryptionKey;\n            if (string.IsNullOrEmpty(newEncryptionPrivateKey) || newEncryptionPrivateKey.Length != 16)\n                throw new NopException(await _localizationService.GetResourceAsync(\"Admin.Configuration.Settings.GeneralCommon.EncryptionKey.TooShort\"));\n\n            var oldEncryptionPrivateKey = securitySettings.EncryptionKey;\n            if (oldEncryptionPrivateKey == newEncryptionPrivateKey)\n                throw new NopException(await _localizationService.GetResourceAsync(\"Admin.Configuration.Settings.GeneralCommon.EncryptionKey.TheSame\"));\n\n            //update password information\n            //optimization - load only passwords with PasswordFormat.Encrypted\n            var customerPasswords = await _customerService.GetCustomerPasswordsAsync(passwordFormat: PasswordFormat.Encrypted);\n            foreach (var customerPassword in customerPasswords)\n            {\n                var decryptedPassword = _encryptionService.DecryptText(customerPassword.Password, oldEncryptionPrivateKey);\n                var encryptedPassword = _encryptionService.EncryptText(decryptedPassword, newEncryptionPrivateKey);\n\n                customerPassword.Password = encryptedPassword;\n                await _customerService.UpdateCustomerPasswordAsync(customerPassword);\n            }\n\n            securitySettings.EncryptionKey = newEncryptionPrivateKey;","sourceCodeStart":1761,"sourceCodeEnd":1797,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Presentation/Nop.Web/Areas/Admin/Controllers/SettingController.cs#L1761-L1797","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Generate exactly 16 characters (mix of letters/digits/symbols) for the new key.","Trim/validate the field client-side to enforce length 16 before submit.","Use a cryptographically random 16-char string (e.g. from a password manager).","Back up the old key before submitting; rotation re-encrypts all Encrypted-format passwords."],"exampleFix":"// before\nif (string.IsNullOrEmpty(newEncryptionPrivateKey) || newEncryptionPrivateKey.Length != 16)\n    throw new NopException(await _localizationService.GetResourceAsync(\"Admin.Configuration.Settings.GeneralCommon.EncryptionKey.TooShort\"));\n\n// after (client-side guard)\n<input asp-for=\"SecuritySettings.EncryptionKey\" minlength=\"16\" maxlength=\"16\" required />\n// and server-side, give a friendlier message:\nif (string.IsNullOrEmpty(newEncryptionPrivateKey) || newEncryptionPrivateKey.Length != 16)\n{\n    _notificationService.ErrorNotification(\"Encryption key must be exactly 16 characters.\");\n    return View(model);\n}","handlingStrategy":"validation","validationCode":"var key = (model.SecuritySettings.EncryptionKey ?? string.Empty).Trim();\nif (key.Length != 16)\n    return ErrorResult(\"Encryption key must be exactly 16 characters.\");","typeGuard":"static bool IsValidEncryptionKey(string key)\n    => !string.IsNullOrWhiteSpace(key) && key.Trim().Length == 16;","tryCatchPattern":"catch (NopException ex) when (ex.Message.Contains(\"EncryptionKey.TooShort\"))\n{ _notificationService.ErrorNotification(\"Key must be 16 chars.\"); return View(model); }","preventionTips":["Generate keys with a password manager set to length 16.","Add minlength/maxlength=16 on the form input.","Back up the old key before rotation."],"tags":["nopcommerce","admin-controller","validation","encryption","security","settings"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}