С# (Mono). Ввод и хэширование пароля. (Ввод через консоль.)

Модератор: Модераторы разделов

_petya_
Сообщения: 53

С# (Mono). Ввод и хэширование пароля.

Сообщение _petya_ »

Есть три вопроса:
1. Как получать код вводимого с клавиатуры символа сразу после нажатия на клавишу(ввод из консоли)? Console.Read возвращает введённый символ только после нажатия на Enter. Ввод пароляя целиком (одной строкой) не подойдёт, т.к. нужно запоминать время ввода каждого символа.
2. Как подавлять вывод вводимых символов на экран или заменять их на звёздочки?
3. Следующий фргамент кода, написанный в тяжких мучениях :), должен хэшировать вводимую с клавиатуры строку. Однако cryptoStream.Read возвращает 0. Не понимаю решительно, в чём проблема.

string input = Console.ReadLine();

MemoryStream stringInMemory = new MemoryStream();
stringInMemory.Capacity = 10000;

StreamWriter writer = new StreamWriter( stringInMemory );
writer.AutoFlush = true;
writer.WriteLine( input );

HashAlgorithm hashAlgorithm = new SHA1CryptoServiceProvider();
ICryptoTransform cryptoTransform = (hashAlgorithm as ICryptoTransform);

CryptoStream cryptoStream = new CryptoStream( stringInMemory , cryptoTransform , CryptoStreamMode.Read );

int result;
byte[] hash = new byte[ 20 ];
result = cryptoStream.Read( hash , 0 , 20 );

Где косяк?

Если кто-нибудь подскажет способ для преобразования типа string в тип byte[] буду крайне признателен.
Спасибо сказали:
Аватара пользователя
Folderx
Сообщения: 296
ОС: fedora, mandriva

Re: С# (Mono). Ввод и хэширование пароля.

Сообщение Folderx »

Код: Выделить всё

#include <stdio.h>
#include <termios.h>

int main() {

   struct termios ekran;
   tcflag_t parametri;
   tcgetattr(0, &ekran);
   parametri = ekran.c_lflag;
   ekran.c_lflag &= ~(ICANON | ECHO);
   tcsetattr(0, TCSANOW, &ekran);

   int vvod;
   do
    vvod = fgetc(stdin);
   while (EOF == vvod);

   // Восстановление значений, которые были изменены в начале.
   tcgetattr(0, &ekran);
   ekran.c_lflag = parametri;
   tcsetattr(0, TCSANOW, &ekran);

   printf("User pressed key %c\n", vvod);
   printf("User pressed key 0x%02x\n", vvod);

   return 0;
}


man stty
там тоже чо-то есть про скрытие ввода
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: С# (Mono). Ввод и хэширование пароля.

Сообщение serzh-z »

Folderx, всё это здорово, спасибо за пример, но автор просил решение для C#...

Даже если в Mono есть доступ к такому низкому уровню как termios (или Curses), очень сомневаюсь, что такое непереносимое/неудобное решение устроит автора.
Спасибо сказали:
_petya_
Сообщения: 53

Re: С# (Mono). Ввод и хэширование пароля.

Сообщение _petya_ »

Вот, собственно, код (ответ на 1 и 2 вопросы). Предоставлен был Ody$$ey на форуме rsdn. Код предназначен для C# 2.0. (CLR 2.0) - структуры ConsoleKeyInfo
и метода ReadKey в версии <2 нет.

static bool EnterPassword()
{
Console.Write("password: ");

_password="";

while(true)
{
ConsoleKeyInfo cki = Console.ReadKey(true);

if(cki.Key == ConsoleKey.Enter)
{
Console.WriteLine();

return true;
}
else
{
if(cki.Key == ConsoleKey.Escape)
{
_password = "";

return false;
}
else
{
if(Char.IsLetterOrDigit(cki.KeyChar) || Char.IsSymbol(cki.KeyChar))
{
_password+=cki.KeyChar;
Console.Write("*");
}
else
{
if(cki.Key == ConsoleKey.Backspace)
{
if(_password.Length > 0)
{
ReplaceEntry(" ", Console.CursorLeft - 1, Console.CursorTop);
_password = _password.Remove(_password.Length - 1);
}
}
else
{
Debug.Assert(false, "Этот случай невозможен! ");
}
}
}
}
}
}

Вопрос 3: перед хэшированием нужно установить позицию в потоке stringInMemory:
...
stringInMemory.Position = 0;
cryptoStream = new CryptoStream ...

Получение типа byte[] из типа string:
byte[] byteArray = System.Text.Encoding.Default.GetBytes( inputString );

Тема м.б. закрыта.
Спасибо сказали: