c# - 为什么我得到 "The input is not a valid Base-64 string"异常

标签 c# xml exception encryption

在我的项目中,我有两种加密和解密 XML 文件的方法

还有另外两种在 XML 文件中保存和加载数据的方法

我不知道为什么我加载数据时会出现这个异常Load()

The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or a non-white space character among the padding characters.

这是我的方法

      public static string Encrypt(string plainText)
      {
            byte[] initVectorBytes = Encoding.ASCII.GetBytes("teto1620@#$%asdf");
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            byte[] keyBytes = Encoding.Unicode.GetBytes("_+)&qwer9512popo");
            var symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
            cryptoStream.FlushFinalBlock();
            byte[] cipherTextBytes = memoryStream.ToArray();
            memoryStream.Close();
            cryptoStream.Close();
            string cipherText = Convert.ToBase64String(cipherTextBytes);
            return cipherText;

      }
      public static string Decrypt(string cipherText)
      {
            byte[] initVectorBytes = Encoding.ASCII.GetBytes("teto1620@#$%asdf");
            byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
            byte[] keyBytes = Encoding.Unicode.GetBytes("_+)&qwer9512popo");
            RijndaelManaged symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
            MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
            CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
            memoryStream.Close();
            cryptoStream.Close();
            string plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
            return plainText;
      }

还有另外两种保存和加载数据的方法

public bool Save()
{
    bool isSaved = false;

    try
    {
        if (SharedData.DeviceList != null)
        {
            var fileInfo = new FileInfo(SharedData.CONFIGURATION_FULL_PATH);
            if (!fileInfo.Exists)
            {
                File.Create(SharedData.CONFIGURATION_FULL_PATH).Close();

            }
            var streamWriter = new StreamWriter(SharedData.CONFIGURATION_FULL_PATH);
            streamWriter.Write(Encrypt("<?xml version=\"1.0\" encoding=\"utf-8\"?><settings>"));
            if (SharedData.DeviceList.Count > 0)
            {
                foreach (var device in SharedData.DeviceList)
                {
                    streamWriter.Write(Encrypt("<username>" +device.Username + "</username>"));
                    streamWriter.Write(Encrypt("<AgentName>" +device.AgentName + "</AgentName>"));
                    streamWriter.Write(Encrypt("<password>" + device.Password + "</password>"));
                    streamWriter.Write(Encrypt("<domain>" + device.Domain + "</domain>"));
                    streamWriter.Write(Encrypt("<peerUri>" + device.PeerURI + "</peerUri>"));
                    streamWriter.Write(Encrypt("<sipUri>" + device.SipURI + "</sipUri>"));
                    streamWriter.Write(Encrypt("<fqdn>" + device.FQDN+ "</fqdn>"));
                    streamWriter.Write(Encrypt("<type>" + ((byte)device.Type).ToString() + "</type>"));
                    streamWriter.Write(Encrypt("<transportType>" +((byte)device.TransportType).ToString() + "</transportType>"));
                }
            }

            streamWriter.Write(Encrypt("</settings>"));
            streamWriter.Close();
            isSaved = true;
        }
        else isSaved = false;
    }
    catch { isSaved = false; }
    return isSaved;
}

private bool Load()
{
    bool isLoaded = false;
    try
    {
        if (SharedData.DeviceList != null)
        {
            var fileInfo = new FileInfo(SharedData.CONFIGURATION_FULL_PATH);
            if (fileInfo.Exists)
            {
                var textTodecrypt = File.ReadAllText(SharedData.CONFIGURATION_FULL_PATH);
                var xmlReader = new XmlTextReader(Decrypt(textTodecrypt));
                var nodeElement = string.Empty;
                var thisDevice = new Device();
                while (xmlReader.Read())
                {
                    if (xmlReader.NodeType == XmlNodeType.Element) nodeElement = xmlReader.Name;
                    if (xmlReader.NodeType == XmlNodeType.Text)
                    {
                        switch (nodeElement)
                        {
                            case @"username":
                                                 if (xmlReader.Value.Length > 0) thisDevice = new Device
                                                                                                {
                                                                                                    Username = xmlReader.Value
                                                                                                };
                                break;
                            case @"AgentName":
                                if (xmlReader.Value.Length > 0)
                                                      thisDevice.AgentName = xmlReader.Value;
                                break;
                            case @"password":
                                if (xmlReader.Value.Length > 0)
                                                      thisDevice.Password = xmlReader.Value;
                                break;
                            case @"peerUri":
                                if (xmlReader.Value.Length > 0)
                                                      thisDevice.PeerURI = xmlReader.Value;
                                break;
                            case @"sipUri":
                                if (xmlReader.Value.Length > 0)
                                                      thisDevice.SipURI = xmlReader.Value;
                                break;
                            case @"domain":
                                if (xmlReader.Value.Length > 0)
                                                      thisDevice.Domain = xmlReader.Value;
                                break;
                            case @"fqdn":
                                if (xmlReader.Value.Length > 0)
                                                      thisDevice.FQDN = xmlReader.Value;
                                break;
                            case @"type":
                                if (xmlReader.Value.Length > 0)
                                                      thisDevice.Type = (Enums.DeviceType)byte.Parse(xmlReader.Value);
                                break;
                            case @"transportType":
                                if (xmlReader.Value.Length > 0)
                                {
                                                      thisDevice.TransportType = (Enums.ServerTransportType)byte.Parse(xmlReader.Value);
                                    if (!IsExist(thisDevice, false)) SharedData.DeviceList.Add(thisDevice);
                                }
                                break;
                        }
                    }
                }
                xmlReader.Close();
                SharedData.TempDeviceList = SharedData.DeviceList;
                isLoaded = true;
            }
            else isLoaded = false;
        }
    }
    catch (Exception)
    {
        isLoaded = false;
    }
    return isLoaded;
}

最佳答案

好的,您的错误是您逐行加密数据并尝试将其作为一个整体解密。

Base64 将每 3 个字节转换为 4 个字符。如果输入数据不是 3 字节的倍数,则编码会添加 1 或 2 个零字节作为填充。然后在流的末尾用一两个“=”字符表示。

现在,如果您尝试解码几个串联的代码块,您很可能会在流中包含“=”字符,这是非法的。

解决方案:重写您的保存方法,首先将所有 xml 实体存储在一个大字符串/内存块中(使用 StringBuilder 或写入 MemoryStream),然后立即对整个数据 block 使用您的加密方法。

关于c# - 为什么我得到 "The input is not a valid Base-64 string"异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11709750/

相关文章:

c# - 为什么 DirectoryEntry ("WinNT://") 不显示组所有人?

javascript - 使用 Javascript 将字符串转换为 E4X XML

eclipse - 子剪辑 : Updating Change Sets for SVNStatusSubscriber (UPDATED - clock sync issue)

c# - 如何创建、读取和写入 XML C# windows 窗体?

c# - 如何在 MVC 应用程序中使用 Microsoft Graph 访问其他用户的资源(特别是电子邮件)?

c# - 在 C# 中将不可序列化对象转换为字符串

c++ - 我可以让 Visual Studio 中断用户定义的 C++ 异常吗?

c++ - 编译器为类生成 noexcept ctor,其成员在没有此类保证的情况下构造

C# XSLT 转换内存不足

android - 以编程方式将 View 添加到 RelativeLayout android