Skip to main content
 首页 » 编程设计

c#之解密在 HTTPS 实例上生成的 WebResource.axd URL

2024年08月06日80qlqwjy

我有下面提到的代码:

string urlEncodedData = URL.Text; 
 
byte[] encryptedData = HttpServerUtility.UrlTokenDecode(urlEncodedData); 
 
Type machineKeySection = typeof(System.Web.Configuration.MachineKeySection); 
Type[] paramTypes = new Type[] { typeof(bool), typeof(byte[]), typeof(byte[]), typeof(int), typeof(int) }; 
MethodInfo encryptOrDecryptData = machineKeySection.GetMethod("EncryptOrDecryptData", BindingFlags.Static | BindingFlags.NonPublic, null, paramTypes, null); 
 
try 
{ 
     byte[] decryptedData = (byte[])encryptOrDecryptData.Invoke(null, new object[] { false, encryptedData, null, 0, encryptedData.Length }); 
     string decrypted = Encoding.UTF8.GetString(decryptedData); 
 
     decryptedLabel.BackColor = Color.Lime; 
     decryptedLabel.Text = decrypted; 
} 
catch (TargetInvocationException) 
{ 
     decryptedLabel.BackColor = Color.Red; 
     decryptedLabel.Text = "Error decrypting data. Are you running your page on the same server and inside the same application as the web resource URL that was generated?"; 
} 

它解密并告诉我有关网络资源的详细信息。 在本地它工作正常。

但是在生产中它总是给我以下来自 catch block 的消息

解密数据时出错。您是否在与生成的网络资源 URL 相同的服务器和相同的应用程序中运行您的页面?

我唯一的区别是生产是在 HTTPS 上进行的。以上代码是否也适用于 HTTPS,还是我必须对其进行更改?

请您参考如下方法:

我也曾使用此代码片段来解密 webresource.axd 参数,但最近它停止工作了。

可能是框架更改为 4.5,因为我在 .net 资源中找到了这条评论 - 页面类,方法 DecryptString http://referencesource.microsoft.com/#System.Web/UI/Page.cs,18cf7b1fe99faea6

if (AspNetCryptoServiceProvider.Instance.IsDefaultProvider) { 
            // ASP.NET 4.5 Crypto DCR: Go through the new AspNetCryptoServiceProvider 
            // if we're configured to do so. 
            ICryptoService cryptoService = AspNetCryptoServiceProvider.Instance.GetCryptoService(purpose, CryptoServiceOptions.CacheableOutput); 
            clearData = cryptoService.Unprotect(protectedData); 
        } 
        else { 
            // If we're not configured to go through the new crypto routines, 
            // fall back to the standard MachineKey crypto routines. 
#pragma warning disable 618 // calling obsolete methods 
            clearData = MachineKeySection.EncryptOrDecryptData(fEncrypt: false, buf: protectedData, modifier: null, start: 0, length: protectedData.Length, useValidationSymAlgo: false, useLegacyMode: false, ivType: IVType.Hash); 
#pragma warning restore 618 // calling obsolete methods 
        }  

您确定唯一的区别是 http 和 https,也许框架版本也是如此?

尽管如此,我使用方法 DecryptString 而不是 EncryptOrDecryptData,下面的代码对我有用。您可以检查这是否也适合您:)

private static string Decrypt(string webResourceParameter) 
    { 
        var purposeType = Type.GetType("System.Web.Security.Cryptography.Purpose, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); 
 
        if (purposeType == null) 
            return null; 
 
        try 
        { 
            var purpose = Activator.CreateInstance(purposeType, "AssemblyResourceLoader.WebResourceUrl"); 
 
            const BindingFlags decryptFlags = BindingFlags.NonPublic | BindingFlags.Static; 
            var decryptString = typeof (Page).GetMethod("DecryptString", decryptFlags); 
 
            var decrypt = decryptString.Invoke(null, new[] {webResourceParameter, purpose}) as string; 
            return decrypt; 
        } 
        catch (Exception ex) 
        { 
            return null; 
        } 
    }