如何在C#中创建密码保护文件

6

这个问题有些相关,但不完全相同。

如何创建一个密码保护的文件?


当你说“密码保护文件”时,你真的应该明确你的意思。你是指当有人试图打开它时,会弹出一个“输入密码”的对话框,还是其他什么? - John Saunders
是的,那确实是我想表达的意思。 - Peter
2个回答

16

加密:

private const int SaltSize = 8;

public static void Encrypt( FileInfo targetFile, string password )
{
  var keyGenerator = new Rfc2898DeriveBytes( password, SaltSize );
  var rijndael = Rijndael.Create();

  // BlockSize, KeySize in bit --> divide by 8
  rijndael.IV = keyGenerator.GetBytes( rijndael.BlockSize / 8 );
  rijndael.Key = keyGenerator.GetBytes( rijndael.KeySize / 8 );

  using( var fileStream = targetFile.Create() )
  {
    // write random salt
    fileStream.Write( keyGenerator.Salt, 0, SaltSize );

    using( var cryptoStream = new CryptoStream( fileStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write ) )
    {
      // write data
    }
  }
}

解密:

public static void Decrypt( FileInfo sourceFile, string password )
{
  // read salt
  var fileStream = sourceFile.OpenRead();
  var salt = new byte[SaltSize];
  fileStream.Read( salt, 0, SaltSize );

  // initialize algorithm with salt
  var keyGenerator = new Rfc2898DeriveBytes( password, salt );
  var rijndael = Rijndael.Create();
  rijndael.IV = keyGenerator.GetBytes( rijndael.BlockSize / 8 );
  rijndael.Key = keyGenerator.GetBytes( rijndael.KeySize / 8 );

  // decrypt
  using( var cryptoStream = new CryptoStream( fileStream, rijndael.CreateDecryptor(), CryptoStreamMode.Read ) )
  {
    // read data
  }
}

如果您在网络通信中使用CryptoStream,应该找到一个流密码。Rijndael通常用作块密码。流密码对于小数据片段是最优的,在喋喋不休的网络流上很典型。与块密码相比,流密码可以更安全,特别是当数据流不是块状时。块密码需要填充和链接。流密码可以花费闲置时间计算更多的伪随机密钥,然后使用非常高效的XOR进行实际的按需加密/解密操作。 - Kind Contributor
1
当我实现这个答案时,只要我提供除正确密码以外的任何密码,就会出现“System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed.” 这不是打败了密码的目的吗?编辑 不,这意味着您必须发现或暴力破解密码才能解密它,这正是密码的目的。Derp. - Overlord Zurg
有没有检测用户输入错误密码的选项? - Johny Corbie
2
拥有一个完整的答案会非常有用,而不仅仅是一些不完整的“//写入数据”和“//读取数据”的部分。比如将一个字符串“Hello World”加密到一个文件中,并将加密后的文件读回到字符串中。 - user2261062

2

使用RijndaelManaged类进行加密,使用Rfc2898DeriveBytes生成用于加密的密钥(和IV)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接