/// <summary> /// Implementation of data recryption /// </summary> /// <param name="storeId">ID of the store context</param> /// <param name="oldKey">Existing key used to encrypt data</param> /// <param name="newKey">New key to be applied to encrypted data</param> private static void InternalRecryptDatabase(int storeId, byte[] oldKey, byte[] newKey) { // WE MUST INITIALIZE THE STORE CONTEXT AS THIS THREAD HAS NO HTTPCONTEXT Store store = StoreDataSource.Load(storeId); if (store != null) { // INITIALIZE THE TOKEN WITH THE STORE CONTEXT Token.Instance.InitStoreContext(store); // PROCESS RECORDS IN BATCHES OF 100 int lastCount = 0; int count = RecryptionHelper.GetRecryptionWorkload(); while ((count > 0) && (count != lastCount)) { List <RecryptRecord> records = RecryptionHelper.LoadForRecrypt(100); foreach (RecryptRecord record in records) { record.DoRecrypt(oldKey, newKey); } // if lastCount and count ever match, it means nothing changed in the last iteration // keep track of this to prevent endless looping in case a recrypt operation fails lastCount = count; count = RecryptionHelper.GetRecryptionWorkload(); } // REMOVE RECRYPT FLAG RecryptionHelper.SetRecryptionFlag(false); } }
/// <summary> /// Decrypts all encrypted data in the database, then re-encrypts it using the new encryption key /// </summary> /// <param name="context">The HttpApplication context to look for the encryption keys</param> public static void RecryptDatabase(HttpApplication context) { // GET OLD AND NEW KEY FROM CONFIG AbleCommerceEncryptionSection encryptionConfig = AbleCommerceEncryptionSection.GetSection(context); byte[] oldKey = encryptionConfig.OldEncryptionKey.GetKey(); byte[] newKey = encryptionConfig.EncryptionKey.GetKey(); RecryptionHelper.RecryptDatabase(oldKey, newKey); }
/// <summary> /// Decrypts all encrypted data in the database, then re-encrypts it using the new encryption key /// </summary> /// <param name="oldKey">The old encryption key</param> /// <param name="newKey">The new encryption key</param> public static void RecryptDatabase(byte[] oldKey, byte[] newKey) { // IF EITHER KEY IS VALID WE SHOULD CONTINUE TO PROCESS // ONE INVALID KEY LIKELY SIGNIFIES UNENCRYPTED DATA if (EncryptionHelper.IsKeyValid(oldKey) || EncryptionHelper.IsKeyValid(newKey)) { RecryptionHelper.LaunchRecryptionOnNewThread(oldKey, newKey); } else { Logger.Error("Error recrypting data, could not find valid keys; Recryption cancelled."); RecryptionHelper.SetRecryptionFlag(false); } }
/// <summary> /// Sets the encryption key for the current application /// </summary> /// <param name="passPhrase">A random string or password that will help form the key.</param> /// <returns></returns> public static byte[] SetEncryptionKey(string passPhrase) { //GET THE ABLECOMMERCE SETTINGS //IF CONFIG IS NULL, WE DO NOT HAVE AN "UPDATABLE" SECTION System.Configuration.Configuration updateableConfig = null; AbleCommerceEncryptionSection encryptionSection = null; try { encryptionSection = AbleCommerceEncryptionSection.GetUpdatableSection(out updateableConfig); } catch { } if (encryptionSection == null) { encryptionSection = AbleCommerceEncryptionSection.GetSection(); } //GENERATE THE KEY byte[] newKey = GetKeyFromPassPhrase(passPhrase); //SAVE THE EXISTING KEY byte[] oldKey = encryptionSection.EncryptionKey.GetKey(); encryptionSection.OldEncryptionKey.SetKey(oldKey); //PRESERVE THE OLD CREATE DATE encryptionSection.OldEncryptionKey.CreateDate = encryptionSection.EncryptionKey.CreateDate; //UPDATE THE KEY encryptionSection.EncryptionKey.SetKey(newKey); //SET THE RECRYPT FLAG RecryptionHelper.SetRecryptionFlag(true); //SAVE SETTINGS AbleCommerceEncryptionSection.UpdateConfig(updateableConfig, encryptionSection); //RECRYPT EXISTING ACCOUNT DATA RecryptionHelper.RecryptDatabase(oldKey, newKey); //RETURN THE GENERATED KEY return(newKey); }