【问题标题】:Invalid length for a Base-64 char array errorBase-64 字符数组错误的长度无效
【发布时间】:2016-01-05 22:37:59
【问题描述】:

正如标题所说,我得到:

Base-64 字符数组的长度无效。

所以我正在做的是使用以下方法构建电子邮件以进行传递:

smsg += "<br><b>To complete your registration, verify your email</b>" + "<a href=" + siteurl + "?usenamw=" + Encrypt(username.Trim()) + "><br>HERE!</a>";

Encrypt 方法如下所示:

private static string Encrypt(string clearText)
{
    string EncryptionKey = "MAKV2SPBNI99212";
    byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
    using (Aes encryptor = Aes.Create())
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV = pdb.GetBytes(16);
        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(clearBytes, 0, clearBytes.Length);
                cs.Close();
            }
            clearText = Convert.ToBase64String(ms.ToArray());
        }
    }
    return clearText;
}

这是 HTML 在 hotmail 中的样子:

http://localhost:30850/Activation.aspx?username=9mQkc5vEebsl2Qg6hbxL+r3KVNhOEsig32oP6eb6rd0=

在接收端,Activation.aspx.cs页面有一行:

String username = Request.QueryString["username"].ToString();
    Label1.Text = Decrypt(username);

还有解密方法:

private string Decrypt(string cipherText)
{
    string EncryptionKey = "MAKV2SPBNI99212";
    byte[] cipherBytes = Convert.FromBase64String(cipherText);
    using (Aes encryptor = Aes.Create())
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV = pdb.GetBytes(16);
        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
            {

                cs.Write(cipherBytes, 0, cipherBytes.Length);
                cs.Close();
            }
            cipherText = Encoding.Unicode.GetString(ms.ToArray());
        }
    }
    return cipherText;
}

所以基本上当我输入像敌人示例乔纳森这样的用户名时,在接收端标签上显示乔纳森没有问题。但是,如果我输入的不是 4 的倍数,我会出错。我知道 Base64 接受 4 的倍数,如果它有 7 个字符,它会增加空间。有什么解决办法吗?非常感谢。

【问题讨论】:

  • usenamw 是错字吗?
  • localhost 对广大受众也没有用处。 :) -- 请更新您的问题。
  • @kfunk 地址在这里完全无关紧要。重要的是加密的用户名参数。乔纳森,错误是发生在 Encrypt 还是 Decrypt 上?
  • @cFrozenDeath 文本仍然具有误导性,它表明该链接背后有有用的信息——“这是 HTML 在 hotmail 中的样子:...”
  • 实际上,我几乎可以肯定这是因为您没有对值进行 url 编码,因此它被错误地读取为 get 参数。见这里:stackoverflow.com/questions/1374753/…

标签: c# asp.net base64


【解决方案1】:

base64 用户名字符串在末尾用 '=' 填充;当 URL 查询字符串被解释时,这将被忽略。即:

username => "9mQkc5vEebsl2Qg6hbxL+r3KVNhOEsig32oP6eb6rd0="

变成:

username => 9mQkc5vEebsl2Qg6hbxL+r3KVNhOEsig32oP6eb6rd0

在请求处理程序中。

您需要先对字符串进行 URL 编码,然后才能在 URL 中使用它。

【讨论】:

    【解决方案2】:

    在 URL 中使用默认的 Base64 字符集是不安全的,尤其是 +(空格)和 =(查询参数的名称/值分隔符)。

    您可以使用修改后的集合(手动将某些字符替换为其他字符一次)或仔细编码您的数据以确保保留每个字符(+ 特别是当 ASP.Net 将其视为空格时)。

    请参阅Base64 on Wikipedia 获取规范链接,查看Passing base64 encoded strings in URL 获取 PHP 中的类似问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      相关资源
      最近更新 更多