{"record":{"id":"fb6556582314fab8","repo":"nopSolutions/nopCommerce","slug":"admin-configuration-settings-generalcommon-encrypt-fb6556","errorCode":null,"errorMessage":"Admin.Configuration.Settings.GeneralCommon.EncryptionKey.TheSame","messagePattern":"Admin\\.Configuration\\.Settings\\.GeneralCommon\\.EncryptionKey\\.TheSame","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"warning","filePath":"src/Presentation/Nop.Web/Areas/Admin/Controllers/SettingController.cs","lineNumber":1783,"sourceCode":"    [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;\n            await _settingService.SaveSettingAsync(securitySettings);\n            await _eventPublisher.PublishAsync(new SecuritySettingsChangedEvent(securitySettings, oldEncryptionPrivateKey));\n\n            _notificationService.SuccessNotification(await _localizationService.GetResourceAsync(\"Admin.Configuration.Settings.GeneralCommon.EncryptionKey.Changed\"));","sourceCodeStart":1765,"sourceCodeEnd":1801,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Presentation/Nop.Web/Areas/Admin/Controllers/SettingController.cs#L1765-L1801","documentation":"Thrown by ChangeEncryptionKey (POST) when the new EncryptionKey equals the currently configured one. Rotation is a no-op in that case, so the action refuses with NopException using the localized 'TheSame' resource. It is a deliberate guard on a destructive operation.","triggerScenarios":"Submitting the same key that is already in SecuritySettings.EncryptionKey; re-pasting the existing key after a failed rotation attempt; operator mistakenly re-entering the current value.","commonSituations":"Operator unsure which key is active and re-submits the current one; attempts to 're-apply' the same key; copy-paste from the same source as the original install.","solutions":["Choose a different 16-char key distinct from the current SecuritySettings.EncryptionKey.","Display the current key fingerprint (not the key itself) so the operator can confirm they are changing it.","Pre-check equality client-side and disable submit when unchanged.","Document that key rotation requires a genuinely new key."],"exampleFix":"// before\nif (oldEncryptionPrivateKey == newEncryptionPrivateKey)\n    throw new NopException(await _localizationService.GetResourceAsync(\"Admin.Configuration.Settings.GeneralCommon.EncryptionKey.TheSame\"));\n\n// after (graceful)\nif (oldEncryptionPrivateKey == newEncryptionPrivateKey)\n{\n    _notificationService.ErrorNotification(\"New key must differ from the current key.\");\n    return View(model);\n}","handlingStrategy":"validation","validationCode":"if (newEncryptionPrivateKey == oldEncryptionPrivateKey)\n    return ErrorResult(\"New key must differ from the current key.\");","typeGuard":"static bool IsKeyChanging(string oldKey, string newKey)\n    => !string.Equals(oldKey, newKey, StringComparison.Ordinal);","tryCatchPattern":"catch (NopException ex) when (ex.Message.Contains(\"EncryptionKey.TheSame\"))\n{ _notificationService.ErrorNotification(\"Choose a different key.\"); return View(model); }","preventionTips":["Show a fingerprint of the current key so operators detect sameness.","Disable submit when new == current.","Use a fresh random source for the new key."],"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"}