2015-02-10 22 views
0

我正在使用的代码波纹管加密和解密文件:如何从CryptoStream的readByte()任意指数(偏移)开始

//加密

UnicodeEncoding UE = new UnicodeEncoding(); 

byte[] key = UE.GetBytes("password"); 

FileStream fsCrypt = new FileStream("cryptFile", FileMode,create); 

RijndaelManaged RMCrypto = new RijndaelManaged(); 

CryptoStream cs = new CryptoStream(fsCrypt, 
       RMCrypto.CreateEncryptor(key, key), 
       CryptoStreamMode.Write); 

FileStream fsIn = new FileStream("FileName", FileMode.Open); 

int data; 
while ((data = fsIn.ReadByte()) != -1) 
     cs.WriteByte((byte)data); 

fsIn.Close(); 
cs.Close(); 
fsCrypt.Close(); 

//解密

UnicodeEncoding UE = new UnicodeEncoding(); 
byte[] key = UE.GetBytes("password"); 

FileStream fsCrypt = new FileStream("filename", FileMode.Open); 

RijndaelManaged RMCrypto = new RijndaelManaged(); 

CryptoStream cs = new CryptoStream(fsCrypt, 
RMCrypto.CreateDecryptor(key, key), 
CryptoStreamMode.Read); 

int data; 
while ((data = cs.ReadByte()) != -1) 
    memorystream.WriteByte((byte)data); 

它运行良好,没有任何问题!

由于某些原因,我在第一个加密文件中添加了10个字节! 其实我已经创建了一个10字节的文件(文件大小正好是10字节),然后我将加密文件附加到这个文件中。

请注意,10字节文件未加密,并且使用简单的文件流创建,并且可以在记事本中读取。

现在在解密代码中,我如何消除前10个字节并解密文件中的剩余数据?我试图调用ReadByte()10次,然后转到WHILE部分和解密文件,但它不起作用,我得到长度无效的异常。

在此先感谢。

+0

在打开CryptoStream之前,您是否尝试调用fsCrypt.ReadByte()10次? – canton7 2015-02-10 14:50:40

+0

是的,我做到了。我在上面的问题中提到过。它不起作用。看起来fsCrypt.ReadByte与简单的fileStream readByte()不同! – user1422847 2015-02-11 05:46:12

+0

你说过“我已经尝试过10次调用ReadByte()” - 你没有在*上说你称它为* - 这里有很多流。 fsCrypt *是一个FileStream - 当你说它必须不同时,我不知道你的意思。无论如何,时间来打破调试器。验证在读取10个字节后,第一段代码中'fsCrypt'的内容与第二段代码中'fsCrypt'的内容匹配。不要尝试解密它,只要确保你正在查看你期望的字节。 – canton7 2015-02-11 10:14:30

回答

2

根据要求发表我的评论作为答案。

你说

我试着打电话给ReadByte()10次,然后转到这个WHILE 部分和解密文件,但它不工作,我得到的长度无效 例外。

,但你不说究竟哪个流你调用ReadByte()10倍,当正是你怎么称呼它。

确保你在fsCrypt之前调用它你实例化新的CryptoStream

还请注意,由于FileStream支持查找,因此您可能只需拨打fsCrypt.Position = 10;fsCrypt.Seek(10, SeekOrigin.Begin),而不是读取10个虚拟字节。

例如:

byte[] key = Encoding.Unicode.GetBytes("password"); 

FileStream fsCrypt = File.OpenRead("filename"); 
fsCrypt.Position = 10; // Skip the 10 useless bytes at the start 

RijndaelManaged rijndaelManaged = new RijndaelManaged(); 

// Disposing CryptoStream will also dispose the FileStream passed to it 
using (CryptoStream cryptoStream = new CryptoStream(fsCrypt, rijndaelManaged.CreateDecryptor(key, key), CryptoStreamMode.Read)) 
{ 
    cryptoStream.CopyTo(memoryStream); 
} 

作为题外话:不要使用作为IV关键!

每次你加密一些东西时IV需要不同,但是可以是公开的。一种常用的技术是每次您想要加密某些东西时随机生成一个IV,并将其作为加密流的前N个字节。当涉及到解密时,请自己读取加密流的前N个字节(在创建CryptoStream之前),将其设置为IV,打开CryptoStream,然后阅读其余部分。

相关问题