加密外部键值缓存存储中的键和值

Encrypt the keys and values in external key-value cache store

我正在将一些数据存储在外部键值存储中。此数据用作缓存。由于数据的性质,我们需要 encrypt/hash 键和值。我们使用 DataProtection APIs 使用默认算法 (AES-256-CBC) 进行加密和解密。 据我所知,在这个算法中,相同的明文加密不会给你相同的密文,所以我不能加密密钥,因为下次我将没有相同的加密密钥来查找。

如果我们对密钥进行哈希处理(使用 SHA-256)而不是对其进行加密,我们实际上可以解决这个问题,但在一些罕见的情况下,哈希处理会导致冲突,而在我们的应用程序中,由于数据的性质,我们不能'甚至连一次碰撞都承担不起。 代码示例:

public class MyClass 
{
    IDataProtector dataProtector;
    ISomeStore externalStore;

    public MyClass(IDataProtectionProvider dataProtectionProvider, ISomeStore externalStore) 
    {
       this.dataProtector = dataProtectionProvider.CreateProtector("somePurposeString");
       this.externalStore = externalStore;
    }

    public string GetOrAddValue(string someKey)
    {
        string encryptedKey = this.dataProtector.Protect(someKey);

        if (this.externalStore.KeyExists(encryptedKey)
        {
           string encryptedValue = this.externalStore.Get(encryptedKey); // lookUp in the cache
           return this.dataProtector.Unprotect(encryptedValue);
        }
        else
        {
           string someValue = GetValue(someKey);
           this.externalStore.Set(encryptedKey, this.dataProtect.Protect(someValue)); // setting the value in the cache
           return someValue;
        }
    }
}

有没有办法高效解决这个问题?来自外部键值存储的平均查找时间约为 100 毫秒。

我不知道你的数据有多大。但是你可以通过这种方式使用散列来将碰撞的几率降低到0。

  1. 在将原始密钥存储到外部存储之前对其进行哈希处理。
  2. 您可以将值调整为 key:value 的字典,其中键是原始键,值是原始值。
  3. 在将值(现在是字典)存储到存储之前对其进行加密。
  4. 下一次,当你想进行查找时。首先散列原始密钥并检查匹配项。如果匹配则解密字典值并在字典中查找原始密钥。如果匹配那么好。如果找不到原始密钥,则将新密钥和新值附加到该字典中,然后再次加密整个字典并将其存储在您的商店中。

这会将冲突减少到 0,但这会增加负载大小,这在您的情况下可能不是您想要的。