№ попытки
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
9
|
10
|
Время ввода
пароля для схемы треугольника, с
|
34
|
32
|
27
|
30
|
24
|
27
|
36
|
28
|
25
|
24
|
Время ввода
пароля для схемы пересечения диагоналей, с
|
40
|
9
|
38
|
42
|
41
|
37
|
35
|
37
|
32
|
33
|
На второй сессии, одну неделю спустя, все участники были в
состоянии правильно ввести свой пароль за меньшее время.
Были проанализированы данные интервью, чтобы понять,
насколько удобна та и другая схемы. Десять участников сообщили, что они
действительно нашли это забавным. Троим участникам ввод пароля не показался забавным,
наоборот, они нашли его скучным и однообразным. Двое участников не имели
конкретного мнения о предложенных схемах.
Когда участники определили местоположение своих парольных
изображений, они должны были мысленно сформировать треугольник в схеме треугольника
или диагонали четырехугольника в схеме диагоналей. Участники заметили, что
формирование треугольника проще и занимает меньше времени, чем формирование
четырехугольника и его диагоналей. Кроме того, важно внимательно выбрать точку
пересечения диагоналей и не ошибиться, иначе игры будет проиграна.
V.
Исследование безопасности
Атака методом
нажатия наудачу на схему треугольника
Злоумышленник всегда может попытаться войти в систему,
нажимая на изображения наугад. Чтобы оценить вероятность этой атаки, нужно
посчитать число всевозможных треугольников n, посчитать площадь
каждого треугольника Si (i=1…n). Вероятность входа
будет рассчитываться по формуле:
(где S - площадь окна для ввода пароля).
Для того чтобы посчитать вероятность случайного входа в систему
была написана программа, которая считает вероятность случайным кликом мыши
попасть в площадь треугольника. То есть рассматривался каждый из возможных
треугольников (учитывая все выше приведенные ограничения по площади),
высчитывалась его площадь и вероятность попасть случайным образом по нему.
Чтобы сделать вероятность случайного входа в систему минимальной,
нужно:
· "перемешивать” изображения от раунда
к раунду;
· при генерации окна ввода пароля должна
отслеживать площадь треугольника; когда площадь треугольника превышает треть
всей площади окна ввода пароля, расположение изображений генерировать заново;
· увеличивать числа раундов парольной схемы.
Атака методом
нажатия наудачу на схему диагоналей
При входе в систему пользователю предлагается поле из 154
изображений (14х11). Из них 108 изображений (12х9) могут содержать точку
пересечения диагоналей (крайние изображения не могут содержать его, поскольку в
программе заведомо не может быть вырожденного четырехугольника). Таким образом,
вероятность атаки методом нажатия наудачу на схему диагоналей четырехугольника
для трех раундов составляет
.
Чтобы сделать вероятность случайного входа в систему для
нескольких раундов минимальной, нужно:
· "перемешивать” изображения от раунда
к раунду;
· увеличивать числа раундов парольной схемы.
Атака методом
полного перебора на схему треугольника
Количество возможных паролей есть "биномиальный
коэффициент" (выбор любых К объектов среди N). При N =
399, К = 5 (числа N и K выбраны, исходя из соображений удобства пользователей), число
возможных паролей равно . Это немного больше, чем число
буквенно-цифровых паролей длины 5 . Кроме того, можно ожидать, что пользователь выберет К
изображений довольно случайным образом, или, по крайней мере, злоумышленник не
сможет предсказать, много о том, какие К изображений выберет пользователь. С
другой стороны, большое число возможных буквенно-цифровых паролей является иллюзией: пользователи выбирают
совсем не случайные буквенно-цифровые пароли.
После того, как атакующий видит одно нажатие на экран
пользователем, злоумышленник узнает, что K парольных изображений таковы, что их
треугольник, образованный ими, содержит выбранное пользователем изображением.
Это исключает все K кортежи, которые не содержат выбранное изображение в
треугольнике, образованном ими.
Нападающий может попытаться сделать запись всех возможных
комбинаций изображений, которые не принадлежат паролю. После многих
последовательных наблюдений он может исключить все больше кортежей. Для того
чтобы предположить реальность такого нападения, была написана программа,
которая эмулировала последовательный ввод пароля пользователем и каждый раз
"вычеркивала" те комбинации, которые содержат эти изображения и,
следовательно, точно не могут принадлежать паролю. То есть, если всего 399
изображений, из которых пользователь выбрал 5 для своего пароля, то может быть
всего комбинаций парольных изображений из миллиардов всевозможных комбинаций.
Программа составляет список всех возможных комбинаций и при каждом вводе пароля
вычеркивает те, которые точно ему не принадлежат. Для этого вначале проводим
горизонтальную прямую линию, содержащую место клика мышкой. Любые комбинации из
3 изображений, расположенных выше этой прямой явно не принадлежат паролю.
Аналогично вычеркиваем все комбинации, содержащие любые комбинации из 3
изображений, расположившихся ниже этой прямой. Далее также точно проводится
вертикальная прямая и отбрасывается еще часть комбинаций.
Результат выполнения этой программы показал, что нужно около 800
полноценных записей входа в систему, чтобы определить пароль пользователя. То
есть если пользователь будет входить в систему каждый день в среднем по 2 раза,
включая выходные и праздники, злоумышленнику придется подсматривать за ним
почти 5 месяцев. За это время можно несколько раз сменить пароль. Таким
образом, нападение с помощью атаки методом полного перебора практически
неосуществимо.
Атака методом
полного перебора на схему диагоналей
Аналогичным образом подсчитаем вероятность атаки методом
полного перебора на схему пересечения диагоналей четырехугольника. Количество
возможных паролей равно
.
После того, как атакующий видит одно нажатие на экран
пользователем, злоумышленник узнает, что K парольных изображений таковы, что их
четырехугольник, образованный ими, содержит выбранное пользователем
изображением. Это исключает все K кортежи, которые не содержат выбранное
изображение в четырехугольнике, образованном ими.
Вероятность атаки на схему диагоналей четырехугольника
рассчитывается аналогично расчету вероятности данной атаки на схему
треугольника - "вычеркиванием" всех кортежей явно не принадлежащих
паролю. То есть, если всего 399 изображений, из которых пользователь выбрал 5
для своего пароля, то может быть всего комбинаций парольных изображений из миллиарда всевозможных комбинаций.
Программа составляет список всех возможных комбинаций и при каждом вводе пароля
вычеркивает те, которые точно ему не принадлежат. Для этого вначале проводим
горизонтальную прямую линию, содержащую место клика мышкой. Любые комбинации из
4 изображений, расположенных выше этой прямой явно не принадлежат паролю.
Аналогично вычеркиваем все комбинации, содержащие любые комбинации из 4
изображений, расположившихся ниже этой прямой. Далее также точно проводится
вертикальная прямая и отбрасывается еще часть комбинаций.
Результат выполнения этой программы показал, что нужно около 1000
полноценных записей входа в систему, чтобы определить пароль пользователя. То
есть если пользователь будет входить в систему каждый день в среднем по 2 раза,
включая выходные и праздники, злоумышленнику придется подсматривать за ним
почти 6 месяцев. За это время можно несколько раз сменить пароль. Таким
образом, нападение с помощью атаки методом полного перебора практически
неосуществимо.
Чтобы сделать вероятность успешной атаки методом полного перебора
на схемы треугольника и схемы диагоналей четырехугольника минимальной, нужно:
· увеличить общее количество изображений N, а при запросе пароля
отображать только N’ изображений (N ≤ N’ ≤ 2 N);
· увеличить число парольных изображений K, а при запросе пароля
отображать только K’ изображений (3≤K’≤K);
· не рисовать невидимый треугольник или
четырехугольник мышкой при вводе пароля;
· периодически (раз в 3 месяца) менять
пароль пользователя.
Заключение
Графические схемы аутентификации - это попытка разработать
нововведение в безопасности, принимая во внимание особенности восприятия людей.
Можно назвать их примером "удобной безопасности".
В данной работе реализованы две схемы графического пароля,
схема треугольника и схема пересечения диагоналей, которые устойчивы к
подглядыванию. Эти схемы стремятся привлечь пользователя визуальной средой,
похожей на игру, направлены на вызов положительных эмоций пользователя, что
может служить противовесом недостатку большого времени для ввода пароля. Сами
пароли легки для запоминания для большинства пользователей, и запоминание
пароля намного проще, чем буквенно-цифрового.
Эти методы аутентификации могут использоваться для
аутентификации в персональном компьютере, карманном компьютере или для web-аутентификации.
Список
литературы
1. "A Password Scheme Strongly Resistant to Spyware”.
D. Hong, B. Hawes, M. Mattews.
2. "A Shoulder-Surfing Resistant Password Scheme - WIW”.
S. Man, D. Hong, M. Mattews.
. "Design and Evalution of a Shoulder-Surfing
Resistant Graphical Password Scheme”. S. Wiedenbeck, J. Waters, L. Sobrado, J.
- C. Birget.
. "Graphical passwords”. L. Sobrado, J. - C. Birget.
5. Э.
Таненбаум. Современные операционные системы. - М.: Питер, 2002.
Приложения
Приложение 1.
Код PAM-модуля pam_triangle
pam_triangle. cpp
#include <security/pam_modules. h>
#include <security/pam_appl. h>
#include <stdio. h>
#include <string. h>
#include <time. h>
#include <QApplication>
#include <QString>
#include <QPushButton>
#include <QIcon>
#include <QLabel>
#include <QWidget>
#include <QGridLayout>
#include <QTextStream>
#include <QDataStream>
#include <QMessageBox>
#include <QFile>
#include "Counter. h"
#define PAM_SM_AUTH
#define n 399
#define n_pass 5
#define m 154
#define row 14
#define rounds 3square (int x1, int y1, int x2,
int y2, int x3, int y3)
{s= (x2-x1) * (y3-y2) - (x3-x1) * (y2-y1);
if (s<0)=s* (-1);s;
}_EXTERN int pam_sm_authenticate (pam_handle_t
*pamh, int flags, int argc,const char **argv)
{(time (NULL));char *user;retval;ind_i
[n];pictures [m];(int i=0; i<n; i++)_i [i] =i;= pam_get_user (pamh,
&user, 0);d=0, f;(int i=0; i<n; i++)
{=rand
() %n;=ind_i [i];_i [i] =ind_i [d];_i [d] =f;
}b;file
("/etc/triangle/passwords");. open (QIODevice:: ReadOnly);in
(&file);username;
int k
[n_pass] ={0,0,0,0,0};p [n_pass] ={0,0,0,0,0};
{>>
username >> k [0] >> k [1] >> k [2] >> k [3] >> k
[4];
if
(username==uname)
{(int
i=0; i<n_pass; i++)
{[i]
=k [i];
}
}
}locate
[3];
int
passwd_pictures [3];x1=0,y1=0,x2=0,y2=0,x3=0,y3=0,x0,y0;
float
s;app (argc, (char **) argv);(int round=0; round<rounds; round++)
{
{
{(int
i=0; i<3; i++)
{[i]
=rand () %m;
}=locate
[0] %row; y1=locate [0] /row;=locate [1] %row; y2=locate [1] /row;=locate [2]
%row; y3=locate [2] /row;
}(locate
[0] ==locate [1] || locate [1] ==locate [2] || locate [2] ==locate [0]);
s=square
(x1,y1,x2,y2,x3,y3);
}(s<10
&& s<50);
{(int
i=0; i<3; i++)
{_pictures
[i] =rand () %n_pass;
}
}(passwd_pictures
[0] ==passwd_pictures [1] || passwd_pictures [1] ==passwd_pictures [2] ||
passwd_pictures [2] ==passwd_pictures [0]);closed [n];(int i=0; i<n; i++)[i]
=0;(int i=0; i<m; i++)
{j;(i!
=locate [0] && i! =locate [1] && i! =locate [2])
{
{=rand
() %n+1;
}(j==p
[0] || j==p [1] || j==p [2] || j==p [3] || j==p [4] || closed [j-1] ==1);[i]
=j;[j-1] =1;
}
}[locate
[0]] =p [passwd_pictures [0]];[locate [1]] =p [passwd_pictures [1]];[locate
[2]] =p [passwd_pictures [2]];
double
sin1,sin2,sin3;=locate [0] %row; y1=locate [0] /row;
x2=locate
[1] %row; y2=locate [1] /row;=locate [2] %row; y3=locate [2] /row;*widget=new
QWidget ();>move (0,0);*layout=new QGridLayout ();*button;(int i=0; i<m;
i++)
{= new
QPushButton ("");=i%row;
y0=i/row;=
(x1-x0) * (y2-y1) - (x2-x1) * (y1-y0);= (x2-x0) * (y3-y2) - (x3-x2) * (y2-y0);=
(x3-x0) * (y1-y3) - (x1-x3) * (y3-y0);( (sin1>=0 && sin2>=0
&& sin3>=0) || (sin1<=0 && sin2<=0 &&
sin3<=0))
{::
connect (button, SIGNAL (clicked ()),&b,SLOT (auth_ok ()));
}
{::
connect (button, SIGNAL (clicked ()), &b, SLOT (auth_err ()));
}(round==0)::
connect (button, SIGNAL (clicked ()),&app,SLOT (quit ()));:: connect
(button, SIGNAL (clicked ()),widget,SLOT (hide ()));result;(&result)
<< "/etc/triangle/pictures/" << pictures [i]
<<". png";>setIcon (QIcon (result));>setIconSize (QSize
(32,32));>addWidget (button, i/row, i%row);
}*label
= new QLabel ("1. Find your 3 password's pictures. \n2. Imagine a triangle
formed from them. \n3. Click on the picture that belong to the triangle's
area.", widget);>addWidget (label, m/row,m%row,1,-1);>setLayout
(layout);>show ();
}.
exec ();a=b. auth ();(a>=rounds)
{PAM_SUCCESS;
}
{PAM_AUTH_ERR;
}
}_EXTERN
int pam_sm_setcred (pam_handle_t * pamh, int flags, int argc, const char
**argv)
{PAM_SUCCESS;
}
#ifdef
PAM_STATICpam_module _pam_test_modstruct = {
"pam_triangle",_sm_authenticate,_sm_setcred,,,,,
};
#endif
Counter.
cpp
#include
<QFile>
#include
<QTextStream>
#include
<QString>
#include
"Counter. h"Counter:: auth_ok ()
{_num++;
}Counter::
auth_err ()
{_num=0;
}
Counter.
h
#ifndef
COUNTER_H
#define
COUNTER_H
#include
<QObject>
#include
<QString>Counter: public QObject
{_OBJECT:()
{ auth_num=0; }auth () const {return auth_num; }slots:auth_ok ();auth_err
();:auth_num;
};
#endif
Приложение 2. Код PAM-модуля pam_diagonal
pam_diagonal.
cpp
#include
<security/pam_modules. h>
#include
<security/pam_appl. h>
#include
<stdio. h>
#include
<time. h>
#include
<QApplication>
#include
<QString>
#include
<QPushButton>
#include
<QIcon>
#include
<QLabel>
#include
<QWidget>
#include
<QGridLayout>
#include
<QTextStream>
#include
<QDataStream>
#include
<QMessageBox>
#include
<QFile>
#include
"Counter. h"
#define
PAM_SM_AUTH
#define
n 399
#define
n_pass 5
#define
m 154
#define
row 14
#define
rounds 3triangle (int x1, int y1, int x2, int y2, int x3, int y3, int x0, int
y0)
{check=0;sin1=
(x1-x0) * (y2-y1) - (x2-x1) * (y1-y0);sin2= (x2-x0) * (y3-y2) - (x3-x2) *
(y2-y0);sin3= (x3-x0) * (y1-y3) - (x1-x3) * (y3-y0);( (sin1>=0 &&
sin2>=0 && sin3>=0) || (sin1<=0 && sin2<=0
&& sin3<=0))
check=1;check;
}square
(int x1, int y1, int x2, int y2, int x3, int y3)
{s=
(x2-x1) * (y3-y2) - (x3-x1) * (y2-y1);
if
(s<0)=s* (-1);s;
}_EXTERN
int pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc,const char
**argv)
{(time
(NULL));char *user;retval;ind_i [n];pictures [m];(int i=0; i<n; i++)_i [i]
=i;= pam_get_user (pamh, &user, 0);d=0, f;(int i=0; i<n; i++)
{=rand
() %n;=ind_i [i];_i [i] =ind_i [d];_i [d] =f;
}b;file
("/etc/diagonal/passwords");. open (QIODevice:: ReadOnly);in
(&file);username;
int k
[n_pass] ={0,0,0,0,0};p [n_pass] ={0,0,0,0,0};
QString
uname (user);(! in. atEnd ())
{>>
username >> k [0] >> k [1] >> k [2] >> k [3] >> k
[4];
if
(username==uname)
{(int
i=0; i<n_pass; i++)
{[i]
=k [i];
}
}
}locate
[4];
int
passwd_pictures [4];x1=0,y1=0,x2=0,y2=0,x3=0,y3=0,x4=0,y4=0;
int
check;app (argc, (char **) argv);(int round=0; round<rounds; round++)
{
{
{=0;
{(int
i=0; i<4; i++)
{[i]
=rand () %m;
}
}(locate
[0] ==locate [1] || locate [1] ==locate [2] || locate [2] ==locate [0] ||
locate [0] ==locate [3] || locate [1] ==locate [3] || locate [2] ==locate
[3]);=locate [0] %row; y1=locate [0] /row;=locate [1] %row; y2=locate [1]
/row;=locate [2] %row; y3=locate [2] /row;=locate [3] %row; y4=locate [3] /row;
check+=triangle
(x1,y1,x2,y2,x3,y3,x4,y4);+=triangle (x1,y1,x2,y2,x4,y4,x3,y3);+=triangle
(x1,y1,x3,y3,x4,y4,x2,y2);+=triangle (x2,y2,x3,y3,x4,y4,x1,y1);
}(check>0);
}(square
(x1,y1,x2,y2,x3,y3) <7 || square (x1,y1,x2,y2,x4,y4) <7 || square
(x1,y1,x3,y3,x4,y4) <7 || square (x2,y2,x3,y3,x4,y4) <7);
do
{(int
i=0; i<4; i++)
{_pictures
[i] =rand () %n_pass;
}
}(passwd_pictures
[0] ==passwd_pictures [1] || passwd_pictures [1] ==passwd_pictures [2] ||
passwd_pictures [2] ==passwd_pictures [0] || passwd_pictures [0]
==passwd_pictures [3] || passwd_pictures [1] ==passwd_pictures [3] ||
passwd_pictures [2] ==passwd_pictures [3]);closed [n];(int i=0; i<n; i++)[i]
=0;(int i=0; i<m; i++)
{j;(i!
=locate [0] && i! =locate [1] && i! =locate [2] && i!
=locate [3])
{
{=rand
() %n+1;
}(j==p
[0] || j==p [1] || j==p [2] || j==p [3] || j==p [4] || closed [j-1] ==1);[i]
=j;[j-1] =1;
}
}[locate
[0]] =p [passwd_pictures [0]];[locate [1]] =p [passwd_pictures [1]];[locate
[2]] =p [passwd_pictures [2]];[locate [3]] =p [passwd_pictures [3]];buff;X []
={0, 0, 0, 0}; float Y [] ={0,0,0,0};
X [0]
=x1; X [1] =x2; X [2] =x3; X [3] =x4;[0] =y1; Y [1] =y2; Y [2] =y3; Y [3] =y4;
for
(int k=0; k<4; k++)
{(int
i=0; i<3; i++)
{(X
[i] > X [i+1])
{=X
[i];[i] =X [i+1];[i+1] =buff;=Y [i];[i] =Y [i+1];[i+1] =buff;
};
};
};(int
i=0; i<3; i++)
{( (X
[i] ==X [i+1]) && (Y [i] >Y [i+1]))
{=X
[i+1];[i+1] =X [i];[i] =buff;=Y [i+1];[i+1] =Y [i];[i] =buff;
};(Y [0]
>Y [1])
{=X
[0];[0] =X [1];[1] =buff;=Y [0];[0] =Y [1];[1] =buff;
};(Y [3]
>Y [2])
{=X [3];
X [3]
=X [2];[2] =buff;=Y [3];
Y [3] =Y
[2];[2] =buff;
};xp,yp,k1,k2,b1,b2;=
(Y [0] - Y [2]) / (X [0] - X [2]);= (Y [1] - Y [3]) / (X [1] - X [3]);= (X [0]
*Y [2] - Y [0] *X [2]) / (X [0] - X [2]);= (X [1] *Y [3] - Y [1] *X [3]) / (X
[1] - X [3]);= (b1-b2) / (k2-k1);= (k2*b1-k1*b2) / (k2-k1);
int
x0,y0;*widget=new QWidget ();>move (0,0);*layout=new QGridLayout
();*button;(int i=0; i<m; i++)
{= new
QPushButton ("");=i%row;=i/row;(xp-x0<2 && xp-x0>-2
&& yp-y0<2 && yp-y0>-2)
{::
connect (button, SIGNAL (clicked ()),&b,SLOT (auth_ok ()));
}
{::
connect (button, SIGNAL (clicked ()), &b, SLOT (auth_err ()));
}(round==0)::
connect (button, SIGNAL (clicked ()),&app,SLOT (quit ()));:: connect
(button, SIGNAL (clicked ()),widget,SLOT (hide ()));result;(&result)
<< "/etc/diagonal/pictures/" << pictures [i]
<<". png";>setIcon (QIcon (result));>setIconSize (QSize
(32,32));>addWidget (button, i/row, i%row);
}*label
= new QLabel ("1. Find your 4 password's pictures. \n2. Imagine a
quadrangle formed from them. \n3. Click on the picture that contain the point
of intersection quadrangle's diagonals.", widget);>addWidget (label,
m/row,m%row,1,-1);>setLayout (layout);>show ();
}.
exec ();a=b. auth ();(a>=rounds)
{PAM_SUCCESS;
}
{PAM_AUTH_ERR;
}
}_EXTERN
int pam_sm_setcred (pam_handle_t * pamh, int flags, int argc, const char
**argv)
{PAM_SUCCESS;
}
#ifdef
PAM_STATICpam_module _pam_test_modstruct = {
"pam_diagonal",_sm_authenticate,_sm_setcred,,,,,
};
#endif
counter.
cpp
#include
<QFile>
#include
<QTextStream>
#include
<QString>
#include
"Counter. h"Counter:: auth_ok ()
{_num++;
}Counter::
auth_err ()
{_num=0;
}
counter.
h
#ifndef
COUNTER_H
#define
COUNTER_H
#include
<QObject>
#include
<QString>Counter: public QObject
{_OBJECT:()
{ auth_num=0; }auth () const {return auth_num; }slots:auth_ok ();auth_err
();:auth_num;
};
#endif