ygo*_*goe 5 c# encryption cryptography
我在用着AesCryptoServiceProvider来加密和解密磁盘上的 XML 文档。MSDN 参考中有一个很有帮助的示例。我根据给定密码的 SHA-256 哈希生成 AES 密钥。它的前半部分被指定为 IV,因为我不知道这里有什么更好的东西可以使用。据我所知,加密和解密时密钥和IV必须相同。
当我解密文件时,它的开头是这样的:
\n\nI\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdH\xe7\x92\xa7\xef\xbf\xbd-\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd[\xef\xbf\xbd="1.0" encoding="utf-8"?>\nRun Code Online (Sandbox Code Playgroud)\n\n该文档的其余部分完全没问题。正如我所期望的那样,内容后面甚至没有一些随机填充。
\n\n是什么导致文件开头出现这种随机垃圾?
\n\n以下是更多阅读代码:
\n\nusing (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())\n{\n using (SHA256CryptoServiceProvider sha = new SHA256CryptoServiceProvider())\n {\n this.cryptoKey = sha.ComputeHash(Encoding.Unicode.GetBytes(password));\n }\n aes.Key = this.cryptoKey;\n Array.Copy(this.cryptoKey, aes.IV, 16);\n\n ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);\n\n using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))\n using (CryptoStream cs = new CryptoStream(fs, decryptor, CryptoStreamMode.Read))\n using (StreamReader sr = new StreamReader(cs))\n {\n string data = sr.ReadToEnd();\n xdoc.LoadXml(data);\n\n //xdoc.Load(sr);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这就是加密代码:
\n\nXmlWriterSettings xws = new XmlWriterSettings();\nxws.Encoding = Encoding.UTF8;\nxws.Indent = true;\nxws.IndentChars = "\\t";\nxws.OmitXmlDeclaration = false;\n\nusing (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())\n{\n aes.Key = this.cryptoKey;\n Array.Copy(this.cryptoKey, aes.IV, 16);\n\n ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);\n\n using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))\n using (CryptoStream cs = new CryptoStream(fs, encryptor, CryptoStreamMode.Write))\n using (StreamWriter sw = new StreamWriter(cs, Encoding.UTF8))\n {\n XmlWriter writer = XmlWriter.Create(sw, xws);\n xdoc.Save(writer);\n writer.Close();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
首先,不要从临时算法生成密钥材料(是的,在密钥派生方面,SHA256 是一种临时算法)。遵循行业标准并使用值得信赖的基于密码的密钥派生功能。当前标准是PBKDF-2,另请参见RFC2898。.Net 管理的加密实现就是该类Rfc2898DeriveBytes。
其次,您必须向我们展示加密代码。在我看来,您使用的示例附加了在加密流开头使用的 IV。鉴于IV 不应该从密码中派生,这是完全有道理的。密钥和 IV 应源自密码+随机,并且“随机”必须作为文件的一部分发送。