Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 22

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

26.08.2016, 12:05. Показов 2213. Ответов 28

Студворк — интернет-сервис помощи студентам
Здравствуйте. Есть некие данные которые хранятся на диски в зашифрованном виде. Мне нужна как-то с ними работать (чтение, запись и т. п.). Если я расшифрую и загружу эти данные в string, то они будут висеть какое-то в памяти в открытом виде, что нехорошо. Как быть в такой ситуации?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.08.2016, 12:05
Ответы с готовыми решениями:

Обмен данными блоков памяти
составить программу, которая производит обмен данными блоков памяти, хранящих 4 слова и расположенных, начиная с адресов 201FH и 205FH ...

Как работает компьютер с данными в памяти?
Скажите, как работает компьюьтер с данными в памяти? Как компьютер различает, где заканчивается один символ и начинается другой? В Файле...

Инициализация TImage данными из оперативной памяти
Привет! Не подскажите как инициализировать TImage данными из оперативной памяти (gif-файд), а потом сохранить на диск как jpg-файл? ...

28
Эксперт .NET
 Аватар для Rius
13233 / 7729 / 1680
Регистрация: 25.05.2015
Сообщений: 23,548
Записей в блоге: 14
26.08.2016, 12:13
Вынести обработку в обычную C/C++ библиотеку, где время жизни данных будет известно.

Как работать с SecureString?
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
26.08.2016, 12:14
CoderSharp, посмотрите в сторону класса SecureString.
1
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 22
26.08.2016, 12:35  [ТС]
Rius, Psilon, Спасибо. Значит все-таки без C++ не обойтись.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
26.08.2016, 12:36
CoderSharp, при чем тут С++? Это обычный шарповый класс.
0
26.08.2016, 12:37

Не по теме:

p.s. в конце упомянутой мной темы есть ссылка на новую тему того же автора, и там пример этого.

0
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 22
26.08.2016, 12:49  [ТС]
Psilon, про C++ это я не Вам, а Rius. Он советует вынести обработку в C/C++ библиотеку. К тому же с SecureString тоже нужно работать в небезопасном коде или опять же в C/C++.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
26.08.2016, 13:09
Rius, а зачем тут С++?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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; }
    }
}
В каждый момент времени в открытой памяти висит только 1 байт пароля, что собственно небольшая проблема.
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
26.08.2016, 13:22
Цитата Сообщение от Psilon Посмотреть сообщение
_bstr = Marshal.SecureStringToBSTR
По адресу _bstr будет храниться расшифрованный пароль... Смысл тогда в SecureString?

Добавлено через 3 минуты
CoderSharp, что мешает работать не со строкой а с массивом байт?
Создайте класс обёртку в которой данные (массив байт) хранятся в зашифрованному виде и расшифровываются только временно при обращении к определенному байту данных, при этом важно чтобы сами данные не уходили наружу, т.е. если нужно какое-то сравнение, то оно должно выполняться внутри обёртки.
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
26.08.2016, 13:24
NickoTin, В том, что этот пароль можно задиспозить после работы, а строку/массив удалит GC когда ему вздумается (возможно - никогда). Когда данные появляются кратковременно для рассчета хэша и после этого детерменированно удаляются - это не компрометирует пароль.

Добавлено через 1 минуту
Цитата Сообщение от NickoTin Посмотреть сообщение
Создайте класс обёртку в которой данные (массив байт) хранятся в зашифрованному виде и расшифровываются только временно при обращении к определенному байту данных, при этом важно чтобы сами данные не уходили наружу, т.е. если нужно какое-то сравнение, то оно должно выполняться внутри обёртки.
Насколько я могу судить, SecureString как раз и есть такая обертка.
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
26.08.2016, 13:29
Цитата Сообщение от Psilon Посмотреть сообщение
Насколько я могу судить, SecureString как раз и есть такая обертка.
Именно. При использовании Marshal.SecureStringToBSTR весь смысл этой обёртки теряется, т.к. все данные становятся доступны сразу, что нот гуд.

Внутри своей обёртки можно без проблем использовать хоть байтовый массив, хоть SecureString, хоть что угодно, это зависит от внутренней реализации, главное чтобы данные не уходили наружу целиком в открытом виде.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
26.08.2016, 13:32
Правда там нельзя обращаться к определенному байту, но как я уже говорил, основная проблема стринги в том, что она висит в памяти неизвестно сколько, а не в том, что она вообще там есть.

Добавлено через 2 минуты
Цитата Сообщение от NickoTin Посмотреть сообщение
Именно. При использовании Marshal.SecureStringToBSTR весь смысл этой обёртки теряется, т.к. все данные становятся доступны сразу, что нот гуд.
Это единственный способ достучаться до данных (не считая ToString). Собственно сам дотнет в кишках это делает, когда передает эту строку куда-то. Как еще достать данные? А никак. Все равно нужно передавать их целиком.
Because the operating system does not directly support SecureString, you must convert the value of the SecureString object to the required string type before passing the string to a native method. The Marshal class has five methods that do this:
  • Marshal.SecureStringToBSTR, which converts the SecureString string value to a binary string (BSTR) recognized by COM.
  • Marshal.SecureStringToCoTaskMemAnsi and Marshal.SecureStringToGlobalAllocAnsi, which copy the SecureString string value to an ANSI string in unmanaged memory.
  • Marshal.SecureStringToCoTaskMemUnicode and Marshal.SecureStringToCoTaskMemUnicode, which copy the SecureString string value to a Unicode string in unmanaged memory.
Each of these methods creates a clear-text string in unmanaged memory. It is the responsibility of the developer to zero out and free that memory as soon as it is no longer needed. Each of the string conversion and memory allocation methods has a corresponding method to zero out and free the allocated memory
Да, можно сделать чуть безопаснее, чтобы постоянно зашифрованные данные висели в памяти, но я предпочту положиться на реализацию SecureString майкрософта и подзабью на то, что строка сколько-то микросекунд повисит в памяти по заранее неизвестному адресу, чем буду велосипедить собственную (де)шифрацию на лету и накосячу там намного более серьезную уязвимость.

Собственно, я и иду по первому сценарию: преобразую в BSTR, работаю, затем диспозю как можно раньше. Все, как описано в документации.
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
26.08.2016, 13:43
Psilon, ты не понял, ты расшифровываешь данные на весь промежуток жизни экземпляра SecureStringStream, в этом главная проблема. Да SecureString тоже расшифровывает полностью данные, но только на момент изменения этих данных, и после изменения сразу же зашифровывает их обратно, тем самым значительно уменьшая возможность доступа к данным сторонним лицам.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
26.08.2016, 13:50
NickoTin, если я буду расшифровывать всю строку для доступа к 1 символу, имхо это будет хуже, чем просто 1 раз расшифровать.

Любой современный шифр является шифром с гаммированием и требует расшифровки всей части строки, предшествующей некоторому символу чтобы получить его.
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
26.08.2016, 13:53
Цитата Сообщение от Psilon Посмотреть сообщение
это будет хуже, чем просто 1 раз расшифровать
Это небезопасно Ок, каждый останется при своём, пусть ТС решает что ему нужно, версии ему предоставили.
0
Эксперт .NET
 Аватар для Rius
13233 / 7729 / 1680
Регистрация: 25.05.2015
Сообщений: 23,548
Записей в блоге: 14
26.08.2016, 14:00
Код устройства SecureString можно посмотреть здесь: https://github.com/dotnet/core... Windows.cs
Авось пригодится. AppendCharCore, InsertAtCore, RemoveAtCore.
1
0 / 0 / 0
Регистрация: 26.08.2016
Сообщений: 22
26.08.2016, 14:10  [ТС]
NickoTin, Если я Вас правильно понял эту обертку нужно реализовать как небезопасный код?
Например. Мне нужно изменить пароль у Ивана Иванова. Я расшифровываю данные из файла в SecureString, на время получаю string из SecureString, меняю хеш пароля и опять обратно в SecureString. А переменную string сразу уничтожаю.
0
Эксперт .NET
 Аватар для Rius
13233 / 7729 / 1680
Регистрация: 25.05.2015
Сообщений: 23,548
Записей в блоге: 14
26.08.2016, 14:12
Цитата Сообщение от CoderSharp Посмотреть сообщение
А переменную string сразу уничтожаю.
Это невозможно. Именно поэтому и ввели SecureString.
Смысл всего этого - не хранить важные данные в объектах, время жизни которых не управляемо.
0
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
26.08.2016, 14:17
Почему-бы не воспользоваться ProtectedData из неймспейса System.Security.Cryptography?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
26.08.2016, 14:18
Цитата Сообщение от NickoTin Посмотреть сообщение
Это небезопасно
Не представляю ситуации, когда кто-то может этим воспользоваться. Вернее, когда будет разница между "выделили - поработали - быстренько освободили" и "постоянно дешифруем, достаем символ и шифруем" в пользу последнего. Очевидно, чтобы поймать микросекундный инстанс строки нужно постоянно мониторить память, причем делать дельту, мониторить все изменения за все время (короче, профилировать), чтобы затем восстановить ход работы программы и понять значение строки. Но тогда многоразовая расшифровка намного скорее наведет на нужное место: нужно просто 100 раз потыкать так, чтобы 100 раз досталась нужная строка, а потом в профайлере посмотреть, на 100 совпадающих кусков памяти.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.08.2016, 14:18
Помогаю со студенческими работами здесь

Работа с файлами(Запись,чтение,работа с данными)
Здравствуйте, никак не могу осилить файлы... Для начала вот само задание: В справочной автовокзала хранится расписание движения автобусов....

Работа с битами И Работа с символьными данными
1. Ввести 8 символов. В символе с наибольшим кодом заменить 5-й бит единицей, а в символе с наименьшим кодом 6-й бит - нулем. Вывести...

Указатели, функции и динамическое выделение памяти: вывести строки с неповторяющимися данными
Задана матрица A(n,n) ,n<=15 . Написать программу, которая находит и выводит на экран номера тех строк, элементы которых не...

Работа с данными
Задание у меня такое: Создать базу данных пациентов, это я сделала, В одной из таблиц есть поля со списками степени выраженности симптомов...

Работа с данными
Это мой код: $countries = "SELECT ex_orders.orders_status,ex_orders.customers_country, countries.countries_name,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru