내 ASP.NET WebForms 응용 프로그램에서 (이 응용 프로그램은 Windows Server 2008 R2, IIS 7.5 및 런타임 v4.0 통합 모드 응용 프로그램 풀 그렇다면) 데이터를 암호화하고 QueryString에 넣고 System.Security.Cryptography.SymmetricAlgorithm
클래스를 사용하여 데이터를 해독합니다. 하지만 때때로 다음과 같은 예외가 발생하는 데이터 암호 해독에 몇 가지 문제가 있습니다.가끔 잘못된 문자열 오류를 해독하는 동안 오류가 발생했습니다 : System.Security.Cryptography.CryptographicException
Bad Data.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Security.Cryptography.CryptographicException: Bad Data.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[CryptographicException: Bad Data. ]
System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) +33
System.Security.Cryptography.Utils._DecryptData(SafeKeyHandle hKey, Byte[] data, Int32 ib, Int32 cb, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode PaddingMode, Boolean fDone) +0
System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) +313
System.Security.Cryptography.CryptoStream.FlushFinalBlock() +33 Cryptography35.SymmetricEncryptionUtility.DecryptData(Byte[] data, String keyFile) in E:\Documents\@Library\Cryptography35\Cryptography35\SymmetricEncryptionUtility.cs:124 Cryptography35.SymmetricQueryString.SymmetriclyEncryptedQueryString..ctor(String encryptedData, String keyfilename, String algorithmname) in E:\Documents\@Library\Cryptography35\Cryptography35\SymmetricQueryString\SymmetriclyEncryptedQueryString.cs:67 WebForms.Web.Views.purchase_a.GetSymmetriclyEncryptedQueryString() in E:\Documents\WebForms.Web\Views\purchase-a.aspx.cs:35 WebForms.Web.Views.purchase_a.Page_Load(Object sender, EventArgs e) in E:\Documents\WebForms.Web\Views\purchase-a.aspx.cs:56 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
System.Web.UI.Control.OnLoad(EventArgs e) +91
System.Web.UI.Control.LoadRecursive() +74 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207 Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1
내가 지적했듯이, 나는 때때로이 오류가 발생합니다. 내가 잘못하고있는 부분을 모르겠다. (암호화 단계 또는 암호 해독 단계에서) 여기에 내가 사용한 코드가있다.
private SymmetriclyEncryptedQueryString GetSymmetriclyEncryptedQueryString() {
#region _decrypting the value
string KeyFileName;
string AlgorithmName = "DES";
Cryptography35.SymmetricEncryptionUtility.AlgorithmName = AlgorithmName;
KeyFileName = HttpContext.Current.Server.MapPath("~/@config/") + "\\symmetric_key.config";
#endregion
#region _reading and assigning the value
if (Request.QueryString["q"] == null)
throw new NullReferenceException("QueryString value is null on search result page");
SymmetriclyEncryptedQueryString QueryString = new SymmetriclyEncryptedQueryString(Request.QueryString["q"], KeyFileName, AlgorithmName);
#endregion
return QueryString;
}
SymmetriclyEncryptedQueryString
클래스
public class SymmetriclyEncryptedQueryString : System.Collections.Specialized.StringDictionary {
public string KeyFileName { get; set; }
public string AlgorithmName { get; set; }
/// <summary>
/// Use this for encrypte the value
/// </summary>
/// <param name="keyfilename"></param>
/// <param name="algorithmname"></param>
public SymmetriclyEncryptedQueryString(string keyfilename, string algorithmname) {
KeyFileName = keyfilename;
AlgorithmName = algorithmname;
}
/// <summary>
/// Use this for decrypte the value.
/// </summary>
/// <param name="encryptedData"></param>
/// <param name="keyfilename"></param>
/// <param name="algorithmname"></param>
public SymmetriclyEncryptedQueryString(string encryptedData, string keyfilename, string algorithmname) {
#region _initials
KeyFileName = keyfilename;
AlgorithmName = algorithmname;
if (String.IsNullOrEmpty(AlgorithmName)){
SymmetricEncryptionUtility.AlgorithmName = AlgorithmName;
}
else{
SymmetricEncryptionUtility.AlgorithmName = "DES";
}
SymmetricEncryptionUtility.ProtectKey = false;
// Check for encryption key
if (!File.Exists(KeyFileName)){
throw new FileNotFoundException("Keyfilename for SymmetriclyEncryptedQueryString is not found on '" + KeyFileName + "'!");
}
#endregion
//Arrange the data
//In order not to get following exception
//Invalid length for a Base-64 char array.
//byte[] RawData = Convert.FromBase64String(encryptedData);
encryptedData = encryptedData.Replace(" ", "+");
int mod4 = encryptedData.Length % 4;
if (mod4 > 0)
encryptedData += new string('=', 4 - mod4);
// Decrypt data passed in
byte[] RawData = Convert.FromBase64String(encryptedData);
string DecryptedVal = SymmetricEncryptionUtility.DecryptData(RawData, KeyFileName);
string StringData = DecryptedVal;
// Split the data and add the contents
int Index;
string[] SplittedData = StringData.Split(new char[] { '&' });
foreach (string SingleData in SplittedData) {
Index = SingleData.IndexOf('=');
base.Add(
HttpUtility.UrlDecode(SingleData.Substring(0, Index)),
HttpUtility.UrlDecode(SingleData.Substring(Index + 1))
);
}
}
public override string ToString() {
#region _initials
if (String.IsNullOrEmpty(AlgorithmName)) {
SymmetricEncryptionUtility.AlgorithmName = AlgorithmName;
} else {
SymmetricEncryptionUtility.AlgorithmName = "DES";
}
SymmetricEncryptionUtility.ProtectKey = false;
// Check for encryption key
if (!File.Exists(KeyFileName)) {
throw new FileNotFoundException("Keyfilename for AsymmetriclyEncryptedQueryString is not found on '" + KeyFileName + "'!");
}
#endregion
#region _prepare for querystring
// Go through the contents and build a
// typical query string
StringBuilder Content = new StringBuilder();
foreach (string key in base.Keys) {
Content.Append(HttpUtility.UrlEncode(key));
Content.Append("=");
Content.Append(HttpUtility.UrlEncode(base[key]));
Content.Append("&");
}
// Remove the last '&'
Content.Remove(Content.Length - 1, 1);
#endregion
#region _encrypt the contents
// Now encrypt the contents
byte[] data = SymmetricEncryptionUtility.EncryptData(Content.ToString(), KeyFileName);
string EncryptedVal = Convert.ToBase64String(data);
#endregion
return EncryptedVal;
}
}
SymmetricEncryptionUtility
클래스
public static class SymmetricEncryptionUtility {
private static bool _ProtectKey;
private static string _AlgorithmName;
// Shhh!!! Don't tell anybody!
private const string MyKey = "m$%&kljasldk$%/65asjdl";
public static string AlgorithmName {
get { return _AlgorithmName; }
set { _AlgorithmName = value; }
}
public static bool ProtectKey {
get { return _ProtectKey; }
set { _ProtectKey = value; }
}
public static void GenerateKey(string targetFile) {
// Create the algorithm
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
Algorithm.GenerateKey();
// No get the key
byte[] Key = Algorithm.Key;
if (ProtectKey)
{
// Use DPAPI to encrypt key
Key = ProtectedData.Protect(
Key, null, DataProtectionScope.LocalMachine);
}
// Store the key in a file called key.config
using (FileStream fs = new FileStream(targetFile, FileMode.Create))
{
fs.Write(Key, 0, Key.Length);
}
}
public static void ReadKey(SymmetricAlgorithm algorithm, string keyFile)
{
byte[] Key;
using (FileStream fs = new FileStream(keyFile, FileMode.Open))
{
Key = new byte[fs.Length];
fs.Read(Key, 0, (int)fs.Length);
}
if (ProtectKey)
algorithm.Key = ProtectedData.Unprotect(Key, null, DataProtectionScope.LocalMachine);
else
algorithm.Key = Key;
}
public static byte[] EncryptData(string data, string keyFile)
{
// Convert string data to byte array
byte[] ClearData = Encoding.UTF8.GetBytes(data);
// Now Create the algorithm
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
ReadKey(Algorithm, keyFile);
// Encrypt information
MemoryStream Target = new MemoryStream();
// Append IV
Algorithm.GenerateIV();
Target.Write(Algorithm.IV, 0, Algorithm.IV.Length);
// Encrypt actual data
CryptoStream cs = new CryptoStream(Target, Algorithm.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(ClearData, 0, ClearData.Length);
cs.FlushFinalBlock();
// Output the bytes of the encrypted array to the textbox
return Target.ToArray();
}
public static string DecryptData(byte[] data, string keyFile) {
// Now create the algorithm
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
ReadKey(Algorithm, keyFile);
// Decrypt information
MemoryStream Target = new MemoryStream();
// Read IV
int ReadPos = 0;
byte[] IV = new byte[Algorithm.IV.Length];
Array.Copy(data, IV, IV.Length);
Algorithm.IV = IV;
ReadPos += Algorithm.IV.Length;
CryptoStream cs = new CryptoStream(Target, Algorithm.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(data, ReadPos, data.Length - ReadPos);
cs.FlushFinalBlock();
// Get the bytes from the memory stream and convert them to text
return Encoding.UTF8.GetString(Target.ToArray());
}
}
UPDATE 나는 다른 것을 생각. 내 페이지 중 하나에서 나는 다음과 같은 일을하고있다.
protected override void OnInit(EventArgs e) {
string url = Request.Url.AbsoluteUri.ToLower();
if (url.StartsWith("http:"))
{
Response.Redirect(url.Replace("http://", "https://"), true);
}
}
나는 그것이 문제의 원인이라고 생각했다. (내 암호화 된 데이터가 쿼리 문자열 내에 있음을 기억하십시오.) http
에서 해당 페이지에 도달하려고 시도하면 https
및 boom으로 리디렉션됩니다. 그것은 나에게 그 오류를 준다. 이제 오류의 원인을 찾았지만 어쨌든 그렇게해서는 안됩니다.
Don ' – rossum