Change the master key
The master key encrypts the connection strings and second factors in the administration store. Change it when a person who knew it leaves, or if it could have fallen into the wrong hands.
Limit: the change protects only future copies. A copy of the file or a backup that has already fallen into the wrong hands together with the old key still opens the connection strings and the second-factor secrets. In that case, also change the passwords of the logins in the connection strings and set up the second factors again (
reset-totp).
Solution overview
The change works without data loss and with two short restarts of the service: the old key stays
known as “retired” for a while, so that all values still open, and the reseal-store command
re-encrypts them with the new key. Every restart interrupts running requests and open transactions;
so schedule the change for a quiet time.
Implementation
The steps assume an installation with the installation package: program under
%ProgramFiles%\Wkl\Data Gateway, data folder %ProgramData%\Wkl.Data.Gateway, previous key in
geheim\hauptschluessel.key with the ID 1 (default of MasterKeyId). Run them in PowerShell as an
administrator.
Write the new key (32 random bytes) directly to a file in the
geheimfolder. That way it appears neither on the screen nor in the console history; the file inherits the folder's restricted permissions (administrators, System, service account read-only):$secretFolder = Join-Path $env:ProgramData 'Wkl.Data.Gateway\geheim' [IO.File]::WriteAllText((Join-Path $secretFolder 'hauptschluessel-2.key'), [Convert]::ToBase64String([Security.Cryptography.RandomNumberGenerator]::GetBytes(32)))
Enter the change in
appsettings.Local.jsonin the program folder (create the file if it doesn't exist). Not inappsettings.Production.json: that file belongs to the installation program and is rewritten on “Ändern” (Change); a retired key would be lost there. The keys are given as a reference (file:orenv:), never in plain text:{ "Gateway": { "Store": { "MasterKey": "file:C:\\ProgramData\\Wkl.Data.Gateway\\geheim\\hauptschluessel-2.key", "MasterKeyId": "2", "RetiredKeys": [ { "Id": "1", "Key": "file:C:\\ProgramData\\Wkl.Data.Gateway\\geheim\\hauptschluessel.key" } ] } } }- Restart the service (
Restart-Service Wkl.Data.Gateway). All values still open; the service encrypts new and changed ones with the new key. If it doesn't start, the event log names the reason (usually a typo in the path). Run in the program folder:
Set-Location (Join-Path $env:ProgramFiles 'Wkl\Data Gateway') .\dbgwsvc.exe reseal-store
Return value
0: all values have been re-encrypted. The command may run while the service is running. It reads the same configuration as the service from the working directory.- Remove the
RetiredKeysentry and restart the service again. Don't delete the filehauptschluessel.keyas long as backups exist that were written with it (see Notes); instead, keep it together with these backups outside the server. - Create a new backup and back up the new key outside the server, see Backup.
Result: the store now depends only on the new key. The warning at startup that counts values under other keys disappears. Clients read the same data before, during, and after re-encryption.
Notes
- Older backups open only with the old key. Keep it as long as these backups.
- Removed too early? If a key that a value still needs is missing, the service doesn't start and names every affected data source. Enter the old key under
RetiredKeysagain. - A lost key can't be replaced. The values it encrypted have to be entered again: connection strings in Datenquellen (Data sources), second factors by setting them up again.
- Order for an update: first update the service, then change the key—not both in one step.