解密方法不对...解密时CryptoStream是源,要Read不是Write... MemoryStream ms = new MemoryStream(inputByteArray); CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read); cs.Read(...//bolabola自己改吧...
读取流位置的时候设置一下ms.Position=0
应该不是解密方法的错误。 我的另一个加密方法也是用这个解密的。 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);
//下面都一样
不可能不支持,你得用缓冲区读啊...inputByteArray、MemoryStream和CryptoStream都是源,你得新建一个byte[]做缓冲区...例如... byte[] result = new byte[dinputByteArray.Length]; cs.Read(result, 0, result.Length); return result;
刚看到这个帖子,不是因为分少哦。如果我没猜错,你的问题在这里: 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变量存放了你加密后的数据流,可是你却用了两次,第一次用在图片保存上了,以至于在加密数据是对一个非空的流写入,返回的数据是图片数据+加密数据的拼接。
同意楼上,经过试验,已经测试成功 加入红色的有一句话。 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"; } }
解密用"sxm"
?????
MemoryStream ms = new MemoryStream(inputByteArray);
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read);
cs.Read(...//bolabola自己改吧...
我的另一个加密方法也是用这个解密的。 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);
//下面都一样
byte[] result = new byte[dinputByteArray.Length];
cs.Read(result, 0, result.Length);
return result;
你这改了能一样还怪了
前后不着调
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变量存放了你加密后的数据流,可是你却用了两次,第一次用在图片保存上了,以至于在加密数据是对一个非空的流写入,返回的数据是图片数据+加密数据的拼接。
加入红色的有一句话。
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";
}
}
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个字节,因此我让流指针指向开始位置,从开始位置写入,这样就可以完全将以前图片保存时写过的位置全部覆盖掉,重利用了内存流。
这个很关健的说 加上这个就好用了。
谢谢楼上诸位 问题解决了 结贴。