Encryption 将数据安全地存储在内存中(基于密码的加密)

Encryption 将数据安全地存储在内存中(基于密码的加密),encryption,.net-core,cryptography,aes,hsm,Encryption,.net Core,Cryptography,Aes,Hsm,我必须把钥匙储存在内存中。因此,出于安全考虑,我们不能将密钥直接存储到内存中,我们需要以加密的方式存储密钥。因此,我们的想法是以加密的方式存储密钥,在加密操作时,只需解密密钥并使用它,然后处理密钥 因此,我们正在使用BouncyCastle c#版本代码中定义的基于密码的加密(PBE) 代码中的问题是密码在这里被修复了。我必须在运行时生成密码 存储密钥的步骤: 生成密码 创建临时密钥以加密密钥(安全数据) 保存到内存中 执行加密操作的步骤: 生成密码 创建临时密钥以解密密钥(安全数据) 执

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

因此,我们正在使用BouncyCastle c#版本代码中定义的基于密码的加密(PBE)

代码中的问题是密码在这里被修复了。我必须在运行时生成密码

存储密钥的步骤:

  • 生成密码
  • 创建临时密钥以加密密钥(安全数据)
  • 保存到内存中
执行加密操作的步骤:

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

    • 这里有一个想法,这样密码就永远不会在本地VAR之外未加密地存储:

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

      我正在使用.net core,因为我知道ProtectedMemory仅在windows平台上工作,因为它使用windows本机DPAPI。没有看到标记,抱歉。我以后会注意的,谢谢。但是如果可能的话,您可以使用这个想法并将其应用到.net core中。也许.net core上提供的ProtectedData类:ProtectedData vs ProtectedMemory讨论:
      byte[] DefaultCryptoSalt = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };