Работа с конфиденциальными данными в памяти - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Есть некие данные которые хранятся на диски в зашифрованном виде. Мне нужна как-то с ними работать (чтение, запись и т. п.). Если я расшифрую и загружу эти данные в string, то они будут висеть какое-то в памяти в открытом виде, что нехорошо. Как быть в такой ситуации?

Решение задачи: «Работа с конфиденциальными данными в памяти»

textual
Листинг программы
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;
 
namespace ConsoleApplication53
{
    class Program
    {
        static void Main(string[] args)
        {
            string samplePass = "Hello world!";
            using (var md5 = MD5.Create())
            {
                byte[] originalHash = md5.ComputeHash(Encoding.Unicode.GetBytes(samplePass));
                Console.WriteLine(string.Concat(originalHash.Select(x=>x.ToString("X2"))));
                var sec = new SecureString();
                foreach (char c in samplePass)
                {
                    sec.AppendChar(c);
                }
                using (var secureStringStream = new SecureStringStream(sec))
                {
                    byte[] arr = md5.ComputeHash(secureStringStream);
                    Console.WriteLine(string.Concat(arr.Select(x => x.ToString("X2"))));
                }
            }
        }
    }
 
 
    class SecureStringStream : Stream
    {
        private IntPtr _bstr;
 
        public SecureStringStream(SecureString secureString)
        {
            _bstr = Marshal.SecureStringToBSTR(secureString);
            Length = Marshal.ReadInt32(_bstr, -4);
        }
 
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (Position == Length)
                return 0;
            buffer[0] = Marshal.ReadByte(_bstr, (int) Position);
            Position++;
            return 1;
        }
 
        public override long Seek(long offset, SeekOrigin origin)
        {
            switch (origin)
            {
                case SeekOrigin.Begin:
                    return Position = offset;
                case SeekOrigin.End:
                    return Position = Length - offset - 1;
                case SeekOrigin.Current:
                    return Position += offset;
            }
            throw new NotImplementedException();
        }
 
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if (_bstr != IntPtr.Zero)
            {
                Marshal.ZeroFreeBSTR(_bstr);
                _bstr = IntPtr.Zero;
            }
        }
 
        public override void Flush()
        {
            throw new NotImplementedException();
        }
 
        public override void SetLength(long value)
        {
            throw new NotImplementedException();
        }
 
        public override void Write(byte[] buffer, int offset, int count)
        {
            throw new NotImplementedException();
        }
 
        public override bool CanRead { get; } = true;
        public override bool CanSeek { get; } = false;
        public override bool CanWrite { get; } = false;
        public override long Length { get; }
        public override long Position { get; set; }
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 3.867 из 5
Похожие ответы