in my project i have two methods to Encrypt and Decrypt XML file
在我的项目中,我有两个方法来加密和解密XML文件
and another tow methods to save and load data in the XML file
以及在XML文件中保存和加载数据的另两种方法
i don't know why i get this exception when i load data Load()
我不知道为什么加载数据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.
输入不是有效的Base-64字符串,因为它包含一个非base 64字符、两个以上的填充字符或填充字符之间的一个非空白字符。
and this is my methods
这就是我的方法
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;
}
and another two methods to save and load data
另外还有两种保存和加载数据的方法。
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;
}
1 个解决方案
#1
5
Ok, your error is that you encrypt your data line by line and try to decrypt it as a whole block.
好的,您的错误是您对数据行进行逐行加密,并尝试将其作为整个块进行解密。
Base64 converts each 3 bytes to 4 characters. If the input data is not a multiple of 3 bytes, the encoding adds 1 or 2 zero-bytes as padding. This is then indicated by one or two '=' characters at the end of the stream.
Base64将每个3字节转换为4个字符。如果输入数据不是3字节的倍数,那么编码将添加1或2个零字节作为填充。然后在流的末尾用一两个'='字符表示。
Now, if you try to decode several concatenated code blocks you will most likely have '=' characters inside the stream, which is illegal.
现在,如果您尝试解码几个连接的代码块,您很可能在流中有'='字符,这是非法的。
The solution: rewrite your Save-Method to first store all your xml-entities in one big string/memory block (use StringBuilder or write to a MemoryStream) and the use your encrypt method on the whole data block at once.
解决方案:重写保存方法,首先将所有xml实体存储在一个大的字符串/内存块中(使用StringBuilder或写入一个MemoryStream),然后立即在整个数据块上使用加密方法。
#1
5
Ok, your error is that you encrypt your data line by line and try to decrypt it as a whole block.
好的,您的错误是您对数据行进行逐行加密,并尝试将其作为整个块进行解密。
Base64 converts each 3 bytes to 4 characters. If the input data is not a multiple of 3 bytes, the encoding adds 1 or 2 zero-bytes as padding. This is then indicated by one or two '=' characters at the end of the stream.
Base64将每个3字节转换为4个字符。如果输入数据不是3字节的倍数,那么编码将添加1或2个零字节作为填充。然后在流的末尾用一两个'='字符表示。
Now, if you try to decode several concatenated code blocks you will most likely have '=' characters inside the stream, which is illegal.
现在,如果您尝试解码几个连接的代码块,您很可能在流中有'='字符,这是非法的。
The solution: rewrite your Save-Method to first store all your xml-entities in one big string/memory block (use StringBuilder or write to a MemoryStream) and the use your encrypt method on the whole data block at once.
解决方案:重写保存方法,首先将所有xml实体存储在一个大的字符串/内存块中(使用StringBuilder或写入一个MemoryStream),然后立即在整个数据块上使用加密方法。