NUKER - генерация хешей паролей

                   

                    Для генерации хеш-функции пароля случайным образом может быть использован следующий пакет:

 

create or replace package nuker
is
--**************************************************************
-- Вызов всех процедур для генерации хэшей
--**************************************************************
procedure monitor
(p_user in varchar2,             -- имя пользователя для определения пароля
p_hash in varchar2,              -- значение хэша для пароля
p_time in number default 10, -- время в мин, после которого прекращается расчет принудительно
p_start in number default 3    -- количество знаков в пароле мин 3
) ;

--**************************************************************
-- Генерация хэшей в соответствии с параметрами
--**************************************************************
procedure analyzer
(p_hash in varchar2,              -- значение хэша для пароля
p_time in number,                  -- время в мин, после которого прекращается расчет принудительно
p_start in number,                  -- количество знаков в пароле мин 3
v_pass out varchar2,              -- возвращаемый результат - пароль или сообщение
v_runtime out varchar2,          -- возвращаемый результат - затраченное время
v_total_attempts out varchar2 -- возвращаемый результат - количество попыток для определения паролей
);

--********************************************************
-- вычисление случайного значения пароля
--********************************************************
function rand return number;
function rand_max(n IN number) return number;
function rand_pass(siz IN number) return varchar2;

end nuker;
/

 

 

 

 

CREATE OR REPLACE PACKAGE BODY "NUKER"
is

multiplier constant number := 22695477;
increment constant number := 1;
to2_32 constant number := 2 ** 32;
to2_16 constant number := 2 ** 16;
val0x7fff constant number := 32767;
Seed number := 1;

g_crlf char(2) := utl_tcp.CRLF;
g_user varchar2(30);
g_slno number := 0;

g_letters varchar2(26) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
g_numbers varchar2(14) := '0123456789#$_@';

g_count number := 0;
g_begin date := sysdate;
g_time number(12,2) := 0;
--******************************************************************************************
--******************************************************************************************
--******************************************************************************************


--**************************************************************
PROCEDURE monitor
(p_user in varchar2,
p_hash in varchar2,
p_time in number default 10,
p_start in number default 3
)
AS
v_pass varchar2(100);
v_runtime varchar2(100);
v_total_attempts varchar2(100);
l_cr number;
l_sql long;

BEGIN
g_user := upper(ltrim(rtrim(p_user)));

analyzer
(p_hash,
p_time,
p_start,
v_pass,
v_runtime,
v_total_attempts);
commit;

begin -- передача результатов для отправки почтовым сообщением с помощью пакета MAILER
l_cr:=dbms_sql.open_cursor;
l_sql :=
' begin mailer.text_fix(''Analyze message'','||
''''||'RANDOM REPORT for letters - '||p_start||g_crlf||
v_pass||g_crlf||v_runtime||g_crlf||v_total_attempts||g_crlf||
'Date analyze: '||sysdate||'''); end;';
dbms_sql.parse(l_cr,l_sql,dbms_sql.native);
g_slno := dbms_sql.execute(l_cr);
dbms_sql.close_cursor(l_cr);
exception
when others then null;
end;

COMMIT;
exception
when others then
if dbms_sql.is_open(l_cr) then dbms_sql.close_cursor(l_cr); end if;
END;



--**************************************************************
PROCEDURE analyzer
(p_hash in varchar2,
p_time in number,
p_start in number,
v_pass out varchar2,
v_runtime out varchar2,
v_total_attempts out varchar2
)
AS
l_exists number;
l_hold_hash varchar2(20);
l_user_check varchar2(30) := upper(ltrim(rtrim(g_user)));
l_hash_check number := length(ltrim(rtrim(p_hash)));
l_gen_pass varchar2(30);
l_gen_hash varchar2(16);
l_min number := 0;
v_sql varchar2(100);
l_cr_user number;
l_status number;

function alter_user return boolean
is
begin
begin
l_gen_pass := upper(ltrim(rtrim(l_gen_pass)));
v_sql := 'alter user '||l_user_check||' identified by "'||l_gen_pass||'"';
execute immediate v_sql;
dbms_sql.bind_variable(l_cr_user,':a',l_user_check);
l_status := dbms_sql.execute(l_cr_user);
l_status:= dbms_sql.fetch_rows(l_cr_user);
dbms_sql.column_value_char(l_cr_user,1,l_gen_hash);
l_gen_hash := upper(ltrim(rtrim(l_gen_hash)));
g_count := g_count +1;
exception when others then
return false; -- To handle invalid passwords/reserved words
end;
return true;
end;

procedure reset_user
is
begin
if l_exists = 0 then v_sql := 'drop user '||l_user_check;
execute immediate v_sql;
elsif l_exists > 0 then v_sql := 'alter user '||l_user_check||' identified by values '||''''||l_hold_hash||'''';
execute immediate v_sql;
end if;
if dbms_sql.is_open(l_cr_user) then dbms_sql.close_cursor(l_cr_user); end if;
end;

procedure set_message
as
begin
v_runtime := 'Total run time (minutes): '||g_time;
v_total_attempts := 'Total attempts: '||g_count;
reset_user;
end;

procedure set_result
is
begin
v_pass := 'Result for '||l_user_check||' / '||p_hash||' is '||l_gen_pass;
set_message;
end;

procedure set_no_result
is
begin
v_pass := 'For '||l_user_check||' / '||p_hash||g_crlf||'MESSAGE: '||p_time||' minute time limit reached.';
set_message;
end;

procedure set_no_standard
is
begin
v_pass := 'For '||l_user_check||' / '||p_hash||g_crlf||'MESSAGE: Test copmlete - not found.';
set_message;
end;


BEGIN
l_min := p_start;

if l_min <= 3 then
l_min := 3;
elsif l_min >= 30 then
l_min := 30;
elsif l_min is null then
v_pass := 'Invalid min length';
return;
end if;

if l_hash_check != 16 then
v_pass := 'Invalid hash';
return;
end if;

if p_time <= 0 or p_time is null then
v_pass := 'Invalid max time';
return;
end if;

l_cr_user := dbms_sql.open_cursor;
v_sql := 'select password from sys.user$ where name = :a';
dbms_sql.parse(l_cr_user,v_sql,dbms_sql.native);
dbms_sql.define_column_char(l_cr_user, 1,l_gen_hash,30);

--********************************************************
select count(*) into l_exists
from sys.user$
where upper(name) = upper(l_user_check);
if l_exists = 0
then
v_sql := 'create user '||l_user_check|| ' identified by temp';
execute immediate v_sql;
else
select password into l_hold_hash
from sys.user$
where name = l_user_check;
end if;
--************************************************************

--********************************************************
l_gen_pass := l_user_check;
if alter_user then
if l_gen_hash = p_hash then
set_result;
return;
end if;
end if;
--********************************************************

--********************************************************
for i in 1..length(g_letters||g_numbers) loop
l_gen_pass := substr(g_letters||g_numbers,i,1);
if alter_user and l_gen_hash = p_hash then
set_result;
return;
end if;
end loop;
--********************************************************

--********************************************************
for i in 1..length(g_letters||g_numbers) loop
l_gen_pass := substr(g_letters||g_numbers,i,1);
for i2 in 1..length(g_letters||g_numbers) loop
l_gen_pass := l_gen_pass || substr(g_letters||g_numbers,i2,1);
if alter_user and l_gen_hash = p_hash then
set_result;
return;
end if;
l_gen_pass := substr(l_gen_pass,1,1);
end loop;
end loop;
--********************************************************

--********************************************************
loop
l_gen_pass := rand_pass(l_min);
if alter_user and l_gen_hash = p_hash then
set_result;
return;
else
g_time := (sysdate - g_begin) * 1440;
end if;
exit when g_time >= p_time;
end loop;

if g_time >= p_time then
set_no_result;
else
set_no_standard;
end if;
END;

--********************************************************

--********************************************************
FUNCTION rand_pass(siz IN number) return varchar2
is
m number := siz;
c char;
d char;
r varchar2(30) := '';
begin
if m <= 30 then m := m - 1; else m := 30; end if;
for i in 1..m loop
d := substr(g_letters||g_numbers,rand_max(length(g_letters||g_numbers)),1);
r := r || d;
c := substr(g_letters||g_numbers,rand_max(length(g_letters||g_numbers)),1);
end loop;
r := c || r;
return r;
end rand_pass;

--********************************************************
/* Set a max digit for rand (includes max value) */
--********************************************************
FUNCTION rand_max(n IN number) return number is
begin
return mod(rand, n) + 1;
end rand_max;

--********************************************************
/* Actual number generator - select random.rand from dual */
--********************************************************
FUNCTION rand return number is
begin
Seed := mod(multiplier * Seed + increment, to2_32);
return bitand(Seed/to2_16, val0x7fff);
end rand;

begin
select userenv('SESSIONID') into Seed from dual;
end nuker;

/

Сайт создан в системе uCoz