“解密OAEP填充时出错”,同时解密来自表存储

时间:2017-03-10 14:03:12

标签: azure encryption azure-table-storage

寻求您的帮助/支持。 我们需要加密表存储中的数据并解密数据,同时从表存储中提取数据。尝试使用https://github.com/Azure/azure-storage-net中的示例应用程序。 在示例应用程序中,Encryption和Decyption以相同的方法发生。在我的情况下,它在“Decrypt”函数中出现错误,错误是 - “解码OAEP填充时出错”但我们需要两个单独的函数。甚至我们需要通过Table Query提取数据。 请在下面找到我的代码 -

const string DemoTable =“demotable”;

    static void Main(string[] args)
    {            
        RsaKey key = new RsaKey("mydemokey");
        string partitionid = "mydemoid123456";

        EncryptData(partitionid, key);

        DecryptData(partitionid, key);
    }

    public static void EncryptData(string partitionid,  RsaKey rsakey)
    {           
        CloudStorageAccount storageAccount = EncryptionShared.Utility.CreateStorageAccountFromConnectionString();
        CloudTableClient client = storageAccount.CreateCloudTableClient();
        CloudTable table = client.GetTableReference(DemoTable);

        try
        {
            table.Create();

            EncryptedEntity ent = new EncryptedEntity() { PartitionKey = partitionid, RowKey = "DemoKey1" };
            ent.Populate();

            TableRequestOptions insertOptions = new TableRequestOptions()
            {
                EncryptionPolicy = new TableEncryptionPolicy(rsakey, null)
            };                                
            table.Execute(TableOperation.Insert(ent), insertOptions, null);
        }
        catch (Exception ex)
        {
            Console.Write(ex.Message);
        }
    }

    public static void DecryptData(string partitionid, RsaKey rsakey)
    {
        CloudStorageAccount storageAccount = EncryptionShared.Utility.CreateStorageAccountFromConnectionString();
        CloudTableClient client = storageAccount.CreateCloudTableClient();
        CloudTable table = client.GetTableReference(DemoTable);

        try
        {
            EncryptedEntity ent = new EncryptedEntity() { PartitionKey = partitionid, RowKey = "DemoKey1" };
            ent.Populate();
            LocalResolver resolver = new LocalResolver();
            resolver.Add(rsakey);
            TableRequestOptions retrieveOptions = new TableRequestOptions()
            {
                EncryptionPolicy = new TableEncryptionPolicy(null, resolver)
            };
            TableOperation operation = TableOperation.Retrieve(ent.PartitionKey, ent.RowKey);
            TableResult result = table.Execute(operation, retrieveOptions, null);
        }
        catch (Exception ex)
        {
            Console.Write(ex.Message);
        }
    }

}

我是否有任何错误或任何其他选项可用于Encypt并解密表存储​​中的数据(包括分区键)。

Decrypt Error

提前感谢您的帮助。

最诚挚的问候, Debasis

1 个答案:

答案 0 :(得分:0)

根据您的代码,我发现您在DecryptData方法中将rsakey添加到LocalResolver对象。

据我所知,raskey是一次性使用的对称密钥,生成后其值不相同。

如果您没有使用正确的raskey(更新表实体时生成),则无法从表存储中获得正确的结果。

有关客户端加密如何工作的更多详细信息,请参阅以下步骤和链接:

通过信封技术进行加密的方式如下:

  1. Azure存储客户端库生成内容加密密钥(CEK),这是一次性使用的对称密钥。
  2. 使用此CEK加密用户数据。
  3. 然后使用密钥加密密钥(KEK)对CEK进行包装(加密)。 KEK由密钥标识符标识,可以是非对称密钥对或对称密钥,可以在本地管理或存储在Azure Key Vaults中。 存储客户端库本身永远不能访问KEK。该库调用Key Vault提供的密钥包装算法。如果需要,用户可以选择使用自定义提供程序进行密钥换行/解包。
  4. 然后将加密数据上载到Azure存储服务。包装的密钥以及一些其他加密元数据可以存储为元数据(在blob上),也可以使用加密数据(队列消息和表实体)进行插值。
  5. 通过信封技术解密的方式如下:

    1. 客户端库假定用户在本地或Azure Key Vaults中管理密钥加密密钥(KEK)。用户不需要知道用于加密的特定密钥。相反,可以设置和使用将不同密钥标识符解析为密钥的密钥解析器。
    2. 客户端库会下载加密数据以及存储在服务上的任何加密材料。
    3. 然后使用密钥加密密钥(KEK)解包(解密)包装内容加密密钥(CEK)。同样,客户端库无法访问KEK。它只是调用自定义或密钥保管库提供程序的解包算法。
    4. 然后使用内容加密密钥(CEK)解密加密的用户数据。
    5. 链接:https://docs.microsoft.com/en-us/azure/storage/storage-client-side-encryption

      我建议您使用以下代码来获得正确的结果。

      class Program
      {
          const string DemoTable = "demotable";
          const string ConnectionString = "yourconnectionstring";
      
          // For retrieves, a resolver can be set up that will help pick the key based on the key id.
          static LocalResolver resolver = new LocalResolver();
      
          static void Main(string[] args)
          {
              RsaKey key = new RsaKey("mydemokey");
              string partitionid = "mydemoid123456";
              EncryptData(partitionid, key);
              DecryptData(partitionid, key);
          }
      
          public static void EncryptData(string partitionid, RsaKey rsakey)
          {
              CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);
      
              CloudTableClient client = storageAccount.CreateCloudTableClient();
              CloudTable table = client.GetTableReference(DemoTable);
      
              try
              {
                  table.CreateIfNotExists();
                  EncryptedEntity ent = new EncryptedEntity() { PartitionKey = partitionid, RowKey = "DemoKey1" ,Test = "aaaa" };
                  //ent.Populate();
                  TableRequestOptions insertOptions = new TableRequestOptions()
                  {
                      EncryptionPolicy = new TableEncryptionPolicy(rsakey, null)
                  };
                  resolver.Add(rsakey);
                  table.Execute(TableOperation.Insert(ent), insertOptions, null);
              }
              catch (Exception ex)
              {
                  Console.Write(ex.Message);
              }
          }
      
          public static void DecryptData(string partitionid, RsaKey rsakey)
          {
              CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);
              CloudTableClient client = storageAccount.CreateCloudTableClient();
              CloudTable table = client.GetTableReference(DemoTable);
      
              try
              {
                  EncryptedEntity ent = new EncryptedEntity() { PartitionKey = partitionid, RowKey = "DemoKey1" };
                  //ent.Populate();
      
                  TableRequestOptions retrieveOptions = new TableRequestOptions()
                  {
                      EncryptionPolicy = new TableEncryptionPolicy(null, resolver)
                  };
                  TableOperation operation = TableOperation.Retrieve(ent.PartitionKey, ent.RowKey);
                  TableResult result = table.Execute(operation, retrieveOptions, null);
              }
              catch (Exception ex)
              {
                  Console.Write(ex.Message);
              }
          }
      
      }
      

      结果: enter image description here

      此外,上面的示例将密钥值存储在本地,通常我们将使用Azure Key Vault服务来存储密钥。

      更多细节,您可以参考以下链接:

      What is Azure Key Vault?

      Encrypt and decrypt in Microsoft Azure Storage using Azure Key Vault