本帖最后由 sxmonsy 于 2011-04-19 10:29:26 编辑

解决方案 »

  1.   

    加密用"201104"
    解密用"sxm"
    ?????
      

  2.   

    解密方法不对...解密时CryptoStream是源,要Read不是Write...
    MemoryStream ms = new MemoryStream(inputByteArray);
    CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read);
    cs.Read(...//bolabola自己改吧...
      

  3.   

    读取流位置的时候设置一下ms.Position=0
      

  4.   

    应该不是解密方法的错误。
    我的另一个加密方法也是用这个解密的。   public static void EncryptFile(string filePath, string savePath, string keyStr)
            {
                //通过des加密
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();            //通过流打开文件
                FileStream fs = File.OpenRead(filePath);
                //获取文件二进制字符
                byte[] inputByteArray = new byte[fs.Length];
                //读流文件
                fs.Read(inputByteArray, 0, (int)fs.Length);
                //关闭流
                fs.Close();
                //获得加密字符串二进制字符
                byte[] keyByteArray = Encoding.Default.GetBytes(keyStr); 
            
    //下面都一样
      

  5.   

    不可能不支持,你得用缓冲区读啊...inputByteArray、MemoryStream和CryptoStream都是源,你得新建一个byte[]做缓冲区...例如...
    byte[] result = new byte[dinputByteArray.Length];
    cs.Read(result, 0, result.Length);
    return result;
      

  6.   

    用这个方法加密和解密就是正常的 但把参数改为Image img 后就不好用了。
      

  7.   

    Image img ???
    你这改了能一样还怪了
    前后不着调
      

  8.   

    最顶上给的就是我改的用image 做参数的加密方法 麻烦看下 看看哪不着调 谢谢了
      

  9.   

    把图片流 改用base64字符串,然后丢到你以前的加密中就行了
      

  10.   

    看了下代码,你可以检查下是不是已经超int范围了,改用long,分批写入CryptoStream 流试试
      

  11.   

    刚看到这个帖子,不是因为分少哦。如果我没猜错,你的问题在这里:
           public static Byte[] EncryptFile(Image img, string keyStr)
            {
                //通过des加密
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
               MemoryStream ms = new MemoryStream();
                //获取文件二进制字符
                img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] inputByteArray = ms.GetBuffer();

                //获得加密字符串二进制字符
                byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);              //计算指定字节组指定区域哈希值
                SHA1 ha = new SHA1Managed();
                byte[] hb = ha.ComputeHash(keyByteArray);
                //加密密钥数组
                byte[] sKey = new byte[8];
                //加密变量
                byte[] sIV = new byte[8];
                for (int i = 0; i < 8; i++)
                    sKey[i] = hb[i];
                for (int i = 8; i < 16; i++)
                    sIV[i - 8] = hb[i];
                //获取加密密钥
                des.Key = sKey;
                //设置加密初始化向量
                des.IV = sIV;            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);            cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                cs.Close();
                ms.Close();
                return ms.ToArray();
            }
    看红色部分,这里的ms变量存放了你加密后的数据流,可是你却用了两次,第一次用在图片保存上了,以至于在加密数据是对一个非空的流写入,返回的数据是图片数据+加密数据的拼接。
      

  12.   

    同意楼上,经过试验,已经测试成功 
    加入红色的有一句话。
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Security.Cryptography;
    using System.IO;
    using System.Data.OleDb;namespace CommonClass
    {
        public partial class ImageOperae : Form
        {
            public ImageOperae()
            {
                InitializeComponent();
                
            }
            /// <summary>
            /// 加密保存
            /// </summary>
            private void button1_Click(object sender, EventArgs e)
            {
                this.pictureBox1.ImageLocation = @"c:\Winter.jpg";
                if (pictureBox1.Image != null)
                {
                    //进行加密
                    byte[] imgData = CommonClass.ImageOperae.EncryptFile(pictureBox1.Image, "201104");                using (OleDbConnection conn = new OleDbConnection(CommonClass.OleDbHelper.connAutomation))
                    {
                        conn.Open();                    OleDbCommand cmd = new OleDbCommand();
                        cmd.Connection = conn;
                        //cmd.CommandText = "delete from table1";
                        //cmd.ExecuteNonQuery();
                        //cmd.Parameters.Clear();                                        OleDbParameter prm = new OleDbParameter();
                        prm.ParameterName = "@ppp";
                        prm.OleDbType = OleDbType.Binary;
                        prm.Value = imgData;                    cmd.Parameters.Add(prm);                    cmd.CommandText = "insert into table1 (id, [image]) values ('6', ?)";                    int count = cmd.ExecuteNonQuery();
                        MessageBox.Show(count.ToString());                    cmd.Dispose();
                        conn.Close();
                    }
                }
            }
            /// <summary>
            /// 读取文件
            /// </summary>
            private void button2_Click(object sender, EventArgs e)
            {            OleDbConnection conn = new OleDbConnection(CommonClass.OleDbHelper.connAutomation);
                conn.Open();
                OleDbDataAdapter obda = new OleDbDataAdapter("select [image]  from table1 where id=6", conn);
                DataTable dt = new DataTable();
                obda.Fill(dt);
                conn.Close();
                byte[] buffer = dt.Rows[0][0] as byte[];            //解密打开
                MemoryStream ms = new MemoryStream(CommonClass.ImageOperae.DecryptFile(buffer, "201104"));            Image img = Image.FromStream(ms);
                pictureBox1.Image = img;    
            }        /// <summary>
            /// 图片加密
            /// </summary>
            public static Byte[] EncryptFile(Image img, string keyStr)
            {
                //通过des加密
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                MemoryStream ms = new MemoryStream();
                //获取文件二进制字符
                img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] inputByteArray = ms.GetBuffer();            //获得加密字符串二进制字符
                byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);            //计算指定字节组指定区域哈希值
                SHA1 ha = new SHA1Managed();
                byte[] hb = ha.ComputeHash(keyByteArray);
                //加密密钥数组
                byte[] sKey = new byte[8];
                //加密变量
                byte[] sIV = new byte[8];
                for (int i = 0; i < 8; i++)
                    sKey[i] = hb[i];
                for (int i = 8; i < 16; i++)
                    sIV[i - 8] = hb[i];
                //获取加密密钥
                des.Key = sKey;
                //设置加密初始化向量
                des.IV = sIV;            ms = new MemoryStream(); //加上这句话 
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                cs.Close();
                ms.Close();
                return ms.ToArray();
            }        /// <summary>
            /// 图片解密
            /// </summary>
            public static byte[] DecryptFile(byte[] inputByteArray, string keyStr)
            {
                //通过des解密
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();            //密钥数组
                byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);
                //定义哈希变量
                SHA1 ha = new SHA1Managed();
                //计算指定字节组指定区域哈希值
                byte[] hb = ha.ComputeHash(keyByteArray);
                //加密密钥数组
                byte[] sKey = new byte[8];
                //加密变量
                byte[] sIV = new byte[8];
                for (int i = 0; i < 8; i++)
                    sKey[i] = hb[i];
                for (int i = 8; i < 16; i++)
                    sIV[i - 8] = hb[i];
                //获取加密密钥
                des.Key = sKey;
                //加密变量
                des.IV = sIV;
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);            cs.FlushFinalBlock();
                cs.Close();
                ms.Close();
                return ms.ToArray();
            }    }
    }using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;namespace  CommonClass
    {
        public class OleDbHelper
        {
            public static string connAutomation 
                = @"Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa; password=123;Initial Catalog=test;Data Source=.\sql2008";
        }
    }
      

  13.   

    不应该这样写,你加入那代码显然没考虑效率问题。楼主你考虑了内存流的再利用,只是考虑欠缺了。其实只要改动一点点就可以让内存流再利用了。
    byte[] inputByteArray = ms.GetBuffer();
    改为:
    byte[] inputByteArray = ms.ToArray();CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
    前面添加:
    ms.Position = 0;第一处改动非常重要,不能用GetBuffer,也许你觉得GetBuffer效率会高,错了,刚好相反,GetBuffer虽然不用复制数组,但是GetBuffer得到的数组长度往往比ToArray得到的长,超过了实际长度,因为MemoryStream内部分配Buffer大小的时候,总是以一个固定的大小递增着分配的,因此MemoryStream的Length属性不代表那个Buffer的大小,只是有效数据的长度。另外当MemoryStream内容改变时,那个GetBuffer获得的数据也会跟着变,因此不适合MemoryStream的重利用。
    第二处改动之所以可以,因为加密后的流会比加密前多出8个字节,因此我让流指针指向开始位置,从开始位置写入,这样就可以完全将以前图片保存时写过的位置全部覆盖掉,重利用了内存流。
      

  14.   

    ms.Position = 0;
    这个很关健的说 加上这个就好用了。
    谢谢楼上诸位 问题解决了 结贴。