我已经发布了一些关于令牌和密码重置的问题,并且已经设法最终解决了这个问题。谢谢大家!
因此,在阅读某些字符在查询字符串中不起作用之前,我决定对查询字符串进行哈希处理,但正如您所猜测的那样, 加号已被删除 < /强>
如何保护或散列查询字符串?
这是我收到的公司电子邮件中的示例,字符串如下所示:
AweVZe-LujIAuh8i9HiXMCNDIRXfSZYv14o4KX0KywJAGlLklGC1hSw-bJWCYfia-pkBbessPNKtQQ&amp; t = pr&amp; ifl
在我的设置中,我只是使用GUID。但这有关系吗?
在我的场景中,即使没有GIUD,用户也无法访问密码页面。这是因为如果查询字符串与会话变量不匹配,页面设置为重定向onload
是否有办法处理查询字符串以提供上述结果?
这个问题更多的是关于获取知识。
更新
这是哈希码:
public static string QueryStringHash(string input)
{
byte[] inputBytes = Encoding.UTF8.GetBytes();
SHA512Managed sha512 = new SHA512Managed();
byte[] outputBytes = sha512.ComputeHash(inputBytes);
return Convert.ToBase64String(outputBytes);
}
然后我将HASH(UserID)传递给SESSION,然后将其作为查询字符串发送: 在下一页上,Session HASH与Query不同,导致值不匹配并使查询字符串无效。
注意:我创建了一个名为Encryption的类来处理所有哈希和加密。
Session["QueryString"] = Encryption.QueryStringHash(UserID);
Response.Redirect("~/public/reset-password.aspx?uprl=" +
HttpUtility.UrlEncode(Session["QueryString"].ToString()));
我也尝试了本页提到的所有内容,但没有运气:
How do I replace all the spaces with %20 in C#
感谢阅读。
答案 0 :(得分:9)
问题是base64编码使用'+'和'/'字符,这些字符在URL中具有特殊含义。如果要base64编码查询参数,则必须更改这些字符。通常情况下,这是通过将'+'和'/'分别替换为' - '和'_'(短划线和下划线)来完成的,如RFC 4648中所述。
在你的代码中,你会这样做:
public static string QueryStringHash(string input)
{
byte[] inputBytes = Encoding.UTF8.GetBytes();
SHA512Managed sha512 = new SHA512Managed();
byte[] outputBytes = sha512.ComputeHash(inputBytes);
string b64 = Convert.ToBase64String(outputBytes);
b64 = b64.Replace('+', '-');
return b64.Replace('/', '_');
}
在接收端,当然,在调用从base 64转换的方法之前,您需要将' - '和'_'替换为相应的'+'和'/'。
他们建议不要使用填充字符('='),但如果这样做,则应使用URL编码。如果您始终知道编码字符串的长度,则无需传送填充字符。您可以在接收端添加所需的填充字符。但是如果你有可变长度的字符串,那么你需要填充字符。
每次看到查询参数中使用的base 64编码时,就会这样做。它遍布整个地方,也许最常见于YouTube视频ID。
答案 1 :(得分:1)
在我必须在查询字符串中传递哈希之前,我做了一些事情。正如您所经历的那样,当与URL混合时,Base 64可能非常讨厌,因此我决定将其作为十六进制字符串传递。它稍微长一点,但更容易处理。我是这样做的:
首先将二进制转换为十六进制字符串的方法。
private static string GetHexFromData(byte[] bytes)
{
var output = new StringBuilder();
foreach (var b in bytes)
{
output.Append(b.ToString("X2"));
}
return output.ToString();
}
然后反向将十六进制字符串转换回二进制文件。
private static byte[] GetDataFromHex(string hex)
{
var bytes = new List<byte>();
for (int i = 0; i < hex.Length; i += 2)
{
bytes.Add((byte)int.Parse(hex.Substring(i, 2), System.Globalization.NumberStyles.HexNumber));
}
return bytes.ToArray();
}
或者,如果您只需要验证哈希是否相同,只需将两者都转换为十六进制字符串并比较字符串(不区分大小写)。希望这有帮助。