如何解密Azure数据表中QNA机器人的加密对话数据?
解密Azure表存储中Bot Framework的加密对话数据
我来帮你解决这个问题——Bot Framework存在Azure表存储里的加密对话数据,其实是通过ASP.NET Core的数据保护系统(DataProtection)加密的,只要匹配Bot应用的加密配置,就能顺利解密。下面是具体的步骤和注意事项:
一、先搞懂加密的核心逻辑
Bot Framework默认会用DataProtectionProvider来加密状态数据(包括对话、用户数据),加密的密钥通常存储在这几个地方:
- 本地开发时:默认存在本地文件系统
- 部署到Azure App Service时:默认用App Service托管的密钥存储(也可以手动配置到Azure Key Vault或Blob存储)
- 自定义配置:如果你手动指定了密钥存储位置(比如Key Vault),那密钥就存在那里
解密的核心要求是:你的解密程序必须使用和Bot应用完全一致的数据保护配置,包括应用名称、密钥存储位置、用途字符串。
二、具体解密步骤
1. 创建一个解密用的C#项目
你可以新建一个控制台应用或者ASP.NET Core项目,用来加载数据保护配置并解密数据。
2. 配置DataProtectionProvider,和Bot应用保持一致
这是最关键的一步,必须和Bot应用的配置完全匹配,否则解密会失败。
示例1:如果Bot部署在Azure App Service,用默认的密钥存储
using Microsoft.AspNetCore.DataProtection; using Microsoft.Extensions.DependencyInjection; var services = new ServiceCollection(); // 配置数据保护,必须和Bot应用的ApplicationName一致 services.AddDataProtection() .SetApplicationName("YourBotAppName") // 替换成你的Bot应用名称,比如Azure App Service的名称 // 如果Bot应用配置了密钥存储到Blob,加上这一行 .PersistKeysToAzureBlobStorage(new Uri("https://yourstorageaccount.blob.core.windows.net/keys/keys.xml")) // 如果Bot应用用Key Vault保护密钥,加上这一行(需要配置访问权限) .ProtectKeysWithAzureKeyVault("https://yourkeyvault.vault.azure.net/keys/yourkey", "ClientId", "ClientSecret"); var serviceProvider = services.BuildServiceProvider(); // 用途字符串必须和Bot Framework默认的一致,Bot用的是"Microsoft.Bot.Connector.Transcript" var dataProtector = serviceProvider.GetDataProtector("Microsoft.Bot.Connector.Transcript");
示例2:如果是本地开发的Bot,用本地密钥
var services = new ServiceCollection(); services.AddDataProtection() .SetApplicationName("YourBotAppName") .PersistKeysToFileSystem(new DirectoryInfo(@"C:\Users\YourUser\AppData\Local\ASP.NET\DataProtection-Keys")); // 本地密钥存储路径 var serviceProvider = services.BuildServiceProvider(); var dataProtector = serviceProvider.GetDataProtector("Microsoft.Bot.Connector.Transcript");
3. 从Azure表存储读取加密数据
用Azure的表存储SDK读取目标表中的数据,找到存储加密内容的Value字段。
using Azure.Data.Tables; // 替换成你的Azure存储连接字符串和对话表名称(默认表名可能是botstate、transcripts,取决于你的Bot配置) var tableClient = new TableClient("YourAzureStorageConnectionString", "YourBotConversationTableName"); var entities = tableClient.Query<TableEntity>().ToList(); foreach (var entity in entities) { // 获取加密的Value字段 string encryptedContent = entity.GetString("Value"); if (!string.IsNullOrEmpty(encryptedContent)) { // 解密内容 string decryptedContent = dataProtector.Unprotect(encryptedContent); Console.WriteLine("解密后的对话数据:"); Console.WriteLine(decryptedContent); // 如果需要,可以把JSON字符串反序列化成具体的对象 // var conversationData = System.Text.Json.JsonSerializer.Deserialize<YourConversationDataClass>(decryptedContent); } }
4. 解析解密后的内容
解密后的decryptedContent是JSON格式的字符串,你可以直接查看,或者反序列化成你Bot中定义的对话数据类,方便结构化查看。
三、关键注意事项
- 应用名称绝对不能错:
SetApplicationName的参数必须和Bot应用里的完全一致,DataProtection是按应用名称隔离密钥的,名称不对就无法解密。 - 密钥必须可访问:如果密钥存在Azure Key Vault或Blob存储,你的解密程序需要有对应的访问权限(比如Key Vault的Get权限、Blob的读取权限)。
- 用途字符串要匹配:Bot Framework默认用
"Microsoft.Bot.Connector.Transcript"作为加密的用途字符串,解密时必须指定这个值,否则解密会失败。 - 旧版本Bot的兼容:如果你的Bot用的是Bot Framework v3(不是v4),加密机制不同,需要用
BotStateEncryption.UnprotectString方法,并且需要对应的加密密钥(v3通常用配置文件里的MicrosoftAppId和MicrosoftAppPassword来生成密钥)。
内容的提问来源于stack exchange,提问作者Yaduska Thambiaiyah
相关产品推荐
相关产品推荐

