我正在尝试编写一些通过 Url 传递的加密代码。出于这个问题的考虑,我排除了数据的实际加密,只显示了导致问题的代码。
我采用盐值,将其转换为字节数组,然后将其转换为 base64 字符串。我将这个字符串连接到另一个 base64 字符串(以前是一个字节数组)。
这两个 base64 字符串然后被 Url 编码。这是我的代码...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Web;
class RHEncryption
{
private static readonly Encoding ASCII_ENCODING = new System.Text.ASCIIEncoding();
private static readonly string SECRET_KEY = "akey";
private static string md5(string text)
{
return BitConverter.ToString(new MD5CryptoServiceProvider().ComputeHash(ASCII_ENCODING.GetBytes(text))).Replace("-", "").ToLower();
}
public string UrlEncodedData;
public RHEncryption()
{
// encryption object
RijndaelManaged aes192 = new RijndaelManaged();
aes192.KeySize = 192;
aes192.BlockSize = 192;
aes192.Mode = CipherMode.CBC;
aes192.Key = ASCII_ENCODING.GetBytes(md5(SECRET_KEY));
aes192.GenerateIV();
// convert Ivector to base64 for sending
string base64IV = Convert.ToBase64String(aes192.IV);
// salt value
string s = "maryhadalittlelamb";
string salt = s.Substring(0, 8);
// convert to byte array
// and base64 for sending
byte[] saltBytes = ASCII_ENCODING.GetBytes(salt.TrimEnd('\0'));
string base64Salt = Convert.ToBase64String(saltBytes);
//url encode concatenated base64 strings
UrlEncodedData = HttpUtility.UrlEncode(base64Salt + base64IV, ASCII_ENCODING);
}
public string UrlDecodedData()
{
// decode the url encode string
string s = HttpUtility.UrlDecode(UrlEncodedData, ASCII_ENCODING);
// convert back from base64
byte[] base64DecodedBytes = null;
try
{
base64DecodedBytes = Convert.FromBase64String(s);
}
catch (FormatException e)
{
Console.WriteLine(e.Message.ToString());
Console.ReadLine();
}
return s;
}
}
如果我随后调用 UrlDecodedData 方法,我会得到一个
Invalid character in a Base-64 string
异常。这是因为 base64Salt 变量包含无效字符(我猜是行终止)但我似乎无法将其删除。
更新 1
自发布以来我发现的一件事是,如果我更改要编码的字符串的顺序,则不会引发异常。 所以从
更改以下代码UrlEncodedData = HttpUtility.UrlEncode(base64Salt + base64IV, ASCII_ENCODING);
到
UrlEncodedData = HttpUtility.UrlEncode(base64IV + base64Salt, ASCII_ENCODING);
似乎有效,不幸的是我无法重新排序,因为此信息已传递给第三方组件。
最佳答案
这是你的问题:
UrlEncodedData = HttpUtility.UrlEncode(base64Salt + base64IV, ASCII_ENCODING);
...
string s = HttpUtility.UrlDecode(UrlEncodedData, ASCII_ENCODING);
base64DecodedBytes = Convert.FromBase64String(s);
您正在连接两个 Base64 编码的字符串,然后尝试对组合进行 Base64 解码。这仅在您的 base64Salt
是六位的倍数时才有效,而在您的情况下不是。不是这样的倍数的数据使用尾随“=”字符进行 Base64 编码,连接它会将“=”放在字符串的中间,这不是有效的 Base64 字符串。
您必须在编码之前连接原始数据。这仅在您知道原始数据长度时才有效。如果不这样做,则必须分别对 salt 和 vector 进行编码,并将它们连接到 URL;例如http://yoursite/yourPage?salt=mcMDaw%20VUsZX&iv=VUsZXyg6n61e6SavmMrtAWa0A
关于c# - 连接和 Url 编码字符串时 Base-64 字符串中的无效字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2676983/