如何防止用户和其他应用程序访问保存在其内容受密码保护的文件中的数据-仅是流? [英] How to prevent users and other applications from accessing data saved in a file whose content is protected by a password - only streams?

查看:44
本文介绍了如何防止用户和其他应用程序访问保存在其内容受密码保护的文件中的数据-仅是流?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在创建一个业务管理系统,以便将项目文件保存在本地计算机上,但是许多文件可以访问该计算机.为了确保没有人可以打开文件并访问所有数据,我希望文件能够打开后才扔到我的应用程序中.为了做到这一点,我认为为了打开文件,需要输入一些固定的密码,以便我通过流,这是打开文件的唯一方法.

So I am creating a business management system so the project files will be saved locally on the computer but many can access the computer. In order that no one can just open the files and access all the data, I want the file to be able to open just threw my app. In order to do it, I thought that in order to open the file there will be some constant password, that I will pass the stream so this is the only way the file can open.

这可能吗?

要在以下代码中进行更改,我应该做些什么?

what should I change in order to do it in the following code?

Stream SerializeStream = new FileStream(Project_Name, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)

推荐答案

以下是我的个人核心库中的一些想法,用于保存/加载加密的文件或对象和流.

Here are some ideas taken from my personal core library to save/load encrypted files or objects and streams.

using System;
using System.Security;
using System.Security.Cryptography;
using System.Text;

using ( StreamWriter writer = new StreamWriter(filename) )
{
  string password = AskPassword();
  writer.Write(Encrypt(Content, password));
}

using ( StreamReader reader = new StreamReader(filename) )
{
  string password = AskPassword();
  string content = Decrypt(reader.ReadToEnd(), password);
}

static public byte[] Encrypt(byte[] data, string password)
{
  return Encrypt(data, password, DefaultCryptoSalt);
}

static public byte[] Decrypt(byte[] data, string password)
{
  return Decrypt(data, password, DefaultCryptoSalt);
}

static public string Encrypt(string str, string password, byte[] salt)
{
  if ( str.IsNullOrEmpty() ) return str;
  PasswordDeriveBytes p = new PasswordDeriveBytes(password, salt);
  var s = Encrypt(Encoding.Default.GetBytes(str), p.GetBytes(32), p.GetBytes(16));
  return Convert.ToBase64String(s);
}

static public string Decrypt(string str, string password, byte[] salt)
{
  if ( str.IsNullOrEmpty() ) return str;
  PasswordDeriveBytes p = new PasswordDeriveBytes(password, salt);
  var s = Decrypt(Convert.FromBase64String(str), p.GetBytes(32), p.GetBytes(16));
  return Encoding.Default.GetString(s);
}

static public byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
  if ( data == null ) return data;
  using ( MemoryStream m = new MemoryStream() )
  {
    var r = Rijndael.Create().CreateEncryptor(key, iv);
    using ( CryptoStream c = new CryptoStream(m, r, CryptoStreamMode.Write) )
      c.Write(data, 0, data.Length);
    return m.ToArray();
  }
}

static public byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
  if ( data == null ) return data;
  using ( MemoryStream m = new MemoryStream() )
  {
    var r = Rijndael.Create().CreateDecryptor(key, iv);
    using ( CryptoStream c = new CryptoStream(m, r, CryptoStreamMode.Write) )
      c.Write(data, 0, data.Length);
    return m.ToArray();
  }
}

特定于您的应用程序的盐示例(使用0到255之间的任意随机值):

Example of salt specific to your app (use any random value between 0 and 255):

byte[] DefaultCryptoSalt = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

您不得将原始密码存储在本地变量之外的任何变量(成员属性和/或字段)中.

You may not store the raw password in any variable (members properties and/or fields) outside local vars.

public string Password
{
  get
  {
    lock ( locker )
    {
      if ( _Password.IsNullOrEmpty() ) return _Password;
      var buf = Encoding.Default.GetBytes(_Password);
      ProtectedMemory.Unprotect(buf, MemoryProtectionScope.SameProcess);
      return Encoding.Default.GetString(Decrypt(buf, _SecureKey.ToString()));
    }
  }
  set
  {
    lock ( locker )
    {
      if ( !MemorizePassword ) return;
      CreateSecureKey();
      if ( value.IsNullOrEmpty() ) _Password = value;
      else
      {
        var buf = Encrypt(Encoding.Default.GetBytes(value), _SecureKey.ToString());
        ProtectedMemory.Protect(buf, MemoryProtectionScope.SameProcess);
        _Password = Encoding.Default.GetString(buf);
      }
    }
  }
}

private void CreateSecureKey()
{
  _SecureKey = new SecureString();
  foreach ( char c in Convert.ToBase64String(CreateCryptoKey(64)) )
    _SecureKey.AppendChar(c);
  _SecureKey.MakeReadOnly();
}

static public byte[] CreateCryptoKey(int length)
{
  if ( length < 1 ) length = 1;
  byte[] key = new byte[length];
  new RNGCryptoServiceProvider().GetBytes(key);
  return key;
}

我希望我没有忘记其他问题.

I hope I have not forgot something else ask it.

如果要序列化和反序列化加密对象,可以执行以下操作:

If you want to serialize and deserialize encrypted objects, you can do things like that:

保存:

using ( FileStream f = new FileStream(filename,
                                      FileMode.Create, FileAccess.Write, FileShare.None,
                                      buffersize) )
{
  var cbf = new BinaryFormatter(new CoreSurrogateSelector(),
                                new StreamingContext(StreamingContextStates.All));
  using ( MemoryStream ms = new MemoryStream() )
  {
    cbf.Serialize(ms, obj);
    var buf = ms.GetBuffer();
    if ( compress ) buf = buf.Compress();
    cbf.Serialize(f, Encrypt(buf, password));
  }
}

加载:

using ( FileStream f = new FileStream(filename,
                                      FileMode.Open, FileAccess.Read, FileShare.None,
                                      buffersize) )
{
  BinaryFormatter bf = new BinaryFormatter(new CoreSurrogateSelector(),
                                           new StreamingContext(StreamingContextStates.All));
  byte[] buf = (byte[])bf.Deserialize(f);
  buf = Decrypt(buf, password);
  if ( compress ) buf = buf.Decompress();
  using ( MemoryStream ms = new MemoryStream() )
  {
    ms.Write(buf, 0, buf.Length);
    ms.Position = 0;
    T obj = (T)bf.Deserialize(ms);
    return obj;
  }
}

如果要使用压缩:

using System;
using System.IO;
using System.IO.Compression;
using System.Text;

static public string Compress(this string text)
{
  if ( text.IsNullOrEmpty() ) return text;
  return Convert.ToBase64String(Encoding.Default.GetBytes(text).Compress());
}

static public byte[] Compress(this byte[] buffer)
{
  using ( MemoryStream ms = new MemoryStream() )
  {
    using ( GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true) )
      zip.Write(buffer, 0, buffer.Length);
    ms.Position = 0;
    byte[] compressed = new byte[ms.Length];
    ms.Read(compressed, 0, compressed.Length);
    byte[] gzBuffer = new byte[compressed.Length + 4];
    System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
    System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
    return gzBuffer;
  }
}

static public string Decompress(this string text)
{
  return Encoding.Default.GetString(Convert.FromBase64String(text).Decompress());
}

static public byte[] Decompress(this byte[] gzBuffer)
{
  using ( MemoryStream ms = new MemoryStream() )
  {
    int msgLength = BitConverter.ToInt32(gzBuffer, 0);
    ms.Write(gzBuffer, 4, gzBuffer.Length - 4);
    byte[] buffer = new byte[msgLength];
    ms.Position = 0;
    using ( GZipStream zip = new GZipStream(ms, CompressionMode.Decompress) )
      zip.Read(buffer, 0, buffer.Length);
    return buffer;
  }
}

这篇关于如何防止用户和其他应用程序访问保存在其内容受密码保护的文件中的数据-仅是流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆