.NET7项目解密OWIN中间件machineKey加密Token的方案
解密OWIN基于machineKey加密的AES Token(.NET7及.NET Framework方案)
1. .NET7中使用DataProtection解密
可以通过.NET7的DataProtection系统兼容machineKey的加密格式,具体操作如下:
- 安装NuGet包:
Microsoft.AspNetCore.DataProtection.SystemWeb - 在
Program.cs中配置DataProtection,绑定现有machineKey的密钥与对应算法:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddDataProtection() .SetApplicationName("匹配原OWIN应用的名称") .UseMachineKey(new MachineKeyProtectionOptions { DecryptionKey = "{decryptionKey}", // 替换为实际decryptionKey值 ValidationKey = "{validationKey}", // 替换为实际validationKey值 DecryptionAlgorithm = "AES", // 对应Token使用的AES加密算法 ValidationAlgorithm = "HMACSHA256" // OWIN默认验证算法,可根据实际调整 }); var app = builder.Build(); // 后续应用配置
配置完成后,注入IDataProtector实例即可解密Token:
public class TokenDecryptor { private readonly IDataProtector _protector; public TokenDecryptor(IDataProtectionProvider provider) { _protector = provider.CreateProtector("原OWIN加密时使用的Purpose标识"); } public string DecryptToken(string encryptedToken) { var decryptedBytes = _protector.Unprotect(Convert.FromBase64String(encryptedToken)); return Encoding.UTF8.GetString(decryptedBytes); } }
2. 直接使用AesCryptoServiceProvider手动解密
OWIN基于machineKey的AES加密格式为[加密数据]+[HMAC验证签名],手动解密需先验证签名再解密数据:
代码示例:
using System.Security.Cryptography; using System.Text; public static string DecryptTokenManually(string encryptedToken, string decryptionKeyHex, string validationKeyHex) { // 将十六进制密钥转换为字节数组 var decryptionKey = HexStringToByteArray(decryptionKeyHex); var validationKey = HexStringToByteArray(validationKeyHex); // 解码Token字节 var tokenBytes = Convert.FromBase64String(encryptedToken); // 拆分加密数据与HMAC签名(HMACSHA256签名长度为32字节) var signatureLength = 32; var encryptedData = tokenBytes.Take(tokenBytes.Length - signatureLength).ToArray(); var signature = tokenBytes.Skip(tokenBytes.Length - signatureLength).ToArray(); // 验证签名合法性 using var hmac = new HMACSHA256(validationKey); var computedSignature = hmac.ComputeHash(encryptedData); if (!computedSignature.SequenceEqual(signature)) { throw new InvalidOperationException("Token签名验证失败"); } // AES解密(OWIN默认CBC模式+PKCS7填充,IV取自加密数据前16字节) using var aes = Aes.Create(); aes.Key = decryptionKey; aes.IV = encryptedData.Take(16).ToArray(); var cipherText = encryptedData.Skip(16).ToArray(); using var decryptor = aes.CreateDecryptor(aes.Key, aes.IV); using var ms = new MemoryStream(cipherText); using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read); using var reader = new StreamReader(cs); return reader.ReadToEnd(); } // 十六进制字符串转字节数组工具方法 private static byte[] HexStringToByteArray(string hex) { hex = hex.Replace("-", ""); var bytes = new byte[hex.Length / 2]; for (int i = 0; i < bytes.Length; i++) { bytes[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16); } return bytes; }
3. .NET Framework中的解决方案
在.NET Framework中,可直接使用System.Web.Security.MachineKey类简化解密流程:
依赖web.config配置的方式
using System.Web.Security; using System.Text; public static string DecryptTokenInNetFramework(string encryptedToken) { // 确保web.config中已配置目标machineKey var decryptedBytes = MachineKey.Decrypt(Convert.FromBase64String(encryptedToken), MachineKeyProtection.All); return Encoding.UTF8.GetString(decryptedBytes); }
手动指定密钥的方式
using System.Web.Configuration; using System.Web.Security; public static string DecryptTokenWithManualKeys(string encryptedToken, string decryptionKey, string validationKey) { // 临时配置machineKey var config = WebConfigurationManager.OpenWebConfiguration("/"); var machineKeySection = (MachineKeySection)config.GetSection("system.web/machineKey"); machineKeySection.DecryptionKey = decryptionKey; machineKeySection.ValidationKey = validationKey; config.Save(); var decryptedBytes = MachineKey.Decrypt(Convert.FromBase64String(encryptedToken), MachineKeyProtection.All); return Encoding.UTF8.GetString(decryptedBytes); }
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

