我正在使用Rijndael
算法加密pdf文件。加密和解密工作正常。加密将pdf文件转换为扩展名为.key
的文件。
问题是我能够在notepad
中打开这个文件(它显示了一些Unicode字符)并破坏它。考虑以下场景:
我已经打开文件,删除一些字符/添加一些字符和save the notepad file
。如果我将这个文件传递给Decryption方法,我将得到损坏的文件作为输出。我知道这是发生的,因为字节流得到变化(填充改变),而在文件中添加或删除字符。
我的问题是:
有办法克服这个问题吗?换句话说,禁用对加密文件的编辑?* *
下面是我用于加密的方法,
<<p> VB代码/strong> Dim plainFile As String = basePath & "cryptoText.pdf"
Dim password As String = "somePass"
Dim UE As New UnicodeEncoding()
Dim key As Byte() = UE.GetBytes(password)
Dim cryptFile As String = basePath & "cryptoText.key"
Dim fsCrypt As New FileStream(cryptFile, FileMode.Create)
Dim RMCrypto As New RijndaelManaged()
Using csKey As New CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write)
Dim FsIn As New FileStream(plainFile, FileMode.Open)
Dim data As Integer
While (data = FsIn.ReadByte()) <> -1
csKey.WriteByte(CByte(data))
End While
FsIn.Close()
End Using
fsCrypt.Close()
c#代码
string plainFile = basePath + "\cryptoText.pdf";
string password = "somePass";
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
string cryptFile = basePath + "\cryptoText.key";
FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
RijndaelManaged RMCrypto = new RijndaelManaged();
using (CryptoStream csKey = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write)) {
FileStream FsIn = new FileStream(plainFile, FileMode.Open);
int data = 0;
while ((data == FsIn.ReadByte()) != -1) {
csKey.WriteByte(Convert.ToByte(data));
}
FsIn.Close();
}
fsCrypt.Close();
注意:我在c#和vb.net中都试过了,所以我把我的问题标记为两者。
答案是做两件事,
- 加密、
- 在加密数据上添加HMAC(如使用相同密钥的SHA256),并将其附加到加密流的末尾
那么当你解密时,你
- 验证HMAC是有效的,
- IFF #1验证,然后且仅然后解密
此外,如果这不是本地文件,而是某种网络流,那么你必须在恒定时间内进行验证——你不能使用普通的字节比较函数。这是因为定时攻击。但是对于本地文件,您可以做任何您喜欢的比较,因为没有定时攻击。
您无法真正阻止任何人在他们喜欢的任何编辑器中打开文件并修改它。将文件标记为只读可能有一点帮助,但不能解决问题。
您应该做的是生成加密文件的散列,然后在解密之前检查以确保文件仍然生成相同的散列。