比如下面的读取dataset:
string connectionStr = "Data Source=lqcomputer;Initial Catalog=mydata;User ID=sa;Password=lqcomputer;";
string sql = "select * from Customers";
SqlConnection conn = new SqlConnection(connectionStr);
conn.Open();SqlDataAdapter ad = new SqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
ad.Fill(ds, "customers");sql = "select * from s_materialinfo";
ad = new SqlDataAdapter(sql, conn);
ad.Fill(ds, "materialinfo");
我用下面的方法加密上面构建的dataset
/// <summary>
/// DataSet加密
/// </summary>
/// <param name="Ds">需要加密的DataSet</param>
/// <param name="sAlgorithm">对称算法实例</param>
/// <returns>加密后的字节流</returns>
private byte[] EncryptDataSet(DataSet Ds, SymmetricAlgorithm sAlgorithm)
{
    MemoryStream sourceStream= new MemoryStream();
    Ds.WriteXml(sourceStream, XmlWriteMode.WriteSchema
    MemoryStream outStream  = new MemoryStream();
    CryptoStream encStream  = new CryptoStream(outStream, sAlgorithm.CreateEncryptor(this.KeyValue, this.IVValue), CryptoStreamMode.Write);
    byte[] bytein           = sourceStream.ToArray();
    encStream.Write(bytein, 0, bytein.Length);    byte[] returnByte = outStream.ToArray();
    encStream.Close();
    outStream.Close();
    sourceStream.Close();
    return returnByte;
}我用下面的方式加密,并形成一个xml文件(内容肯定是乱码)
byte[] encryptByte = this.EncryptDataSet(ds, this.sAlgorithm);  //加密后的数据流
FileStream encryptFileStream = new FileStream("encryptfile.xml", FileMode.OpenOrCreate, FileAccess.Write);
encryptFileStream.Write(encryptByte, 0, encryptByte.Length);    //将加密后的内存流写入指定文件
下面是我的解密方法
/// <summary>
/// DataSet解密
/// </summary>
/// <param name="EncryptByte">加密的字节流</param>
/// <param name="sAlgorithm">对称算法实例</param>
/// <returns>解密后的DataSet</returns>
private byte[] DecryptDataSet(byte[] EncryptByte, SymmetricAlgorithm sAlgorithm)
{
    MemoryStream decryptStream  = new MemoryStream();
    CryptoStream encStream      = new CryptoStream(decryptStream, sAlgorithm.CreateDecryptor(this.KeyValue, this.IVValue), CryptoStreamMode.Write);
    try
    {
encStream.Write(EncryptByte, 0, EncryptByte.Length);
    }
    catch (Exception error)
    {
throw (error);
    }
    finally
    {
//decryptStream.Close();
//encStream.Close();
    }
    return decryptStream.ToArray();
}我以下面的形式进行解密
//解密
byte[] decryptByte = this.DecryptDataSet(encryptByte, this.sAlgorithm);
//MemoryStream decryptMStream = new MemoryStream(decryptByte);
//DataSet decryptDs = new DataSet();
//decryptDs.ReadXml(decryptMStream);FileStream decryptFileStream = new FileStream("decryptfile.xml", FileMode.OpenOrCreate, FileAccess.Write);
decryptFileStream.Write(decryptByte, 0, decryptByte.Length); //将解密后的内存流写入指定文件我发现解密后生成的decryptfile.xml文件与最开始我从数据库读取后未加密形成的xml文件,数据出现了丢失,而且加密算法不同的话,数据丢失的情况也不一样。因此我在使用decryptDs.ReadXml(decryptMStream);将内存流读取到dataset时,就出现了“缺少了根节点”的异常。

解决方案 »

  1.   

    上面的方法中key和iv的值都是有效的,我在加密解密前先生成,作为两个属性值
      

  2.   

    还顺便提一点:
    在解密方法中的finally部分,
    finally
    {
    decryptStream.Close();
    encStream.Close();
    }
    运行到encStream.Close();时提示数据不正确是怎么回事?
      

  3.   

    很可能是你的加密后的 字符串中包含了 影响xml识别的字符,既然是乱码,就不一定要存到xml吧?建议改存为一个二进制文件试试