将数据安全地存储在内存中(基于密码的加密) [英] Store data securely in memory (password based encryption)

查看:34
本文介绍了将数据安全地存储在内存中(基于密码的加密)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须将密钥存储到内存中.所以出于安全考虑,我们不能将加密密钥直接存储到内存中,我们需要以加密方式存储密钥.所以我们的想法是我们以加密的方式存储密钥,在加密操作时,只需解密密钥并使用它并处理密钥.

I have to store the key into memory. So as security concern we can not store the cryptographic key into the memory directly, We need to store the key in Encrypted way. So the idea is we store the key in encrypted manner and at the time of crypto operation, just decrypt the key and use it and dispose the key.

所以我们在 BouncyCastle c# 版本中使用基于密码的加密(PBE)定义 示例代码.

So we are using Password based encryption(PBE) define in BouncyCastle c# version Example code.

代码中的问题是密码在这里是固定的.我必须在运行时生成密码.

The problem in code is that the password is fix here. I have to generate the password at run time.

存储密钥的步骤:

  • 生成密码
  • 创建临时密钥来加密密钥(安全数据)
  • 保存到内存中

执行加密操作的步骤:

  • 生成密码
  • 创建临时密钥来解密密钥(安全数据)
  • 执行加密操作
  • 处理密钥(安全数据)

推荐答案

这里有一个想法,让密码永远不会在本地变量之外未加密的情况下存储:

Here is an idea so the password can be never stored unencrypted outside local vars:

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

private string _SecureKey;

public bool MemorizePassword { get; set; }

public string Password
{
  get
  {
    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
  {
    if ( !MemorizePassword ) 
    { 
      _Password = "";
      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;
}

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();
  }
}

特定于您的应用的 salt 示例(使用 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 };

这篇关于将数据安全地存储在内存中(基于密码的加密)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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