Živě.cz o počítačích a internetu

Tipy a triky v Delphi, díl 184. – bezpečné heslo

Jan Šindelář 11.5.2005

Vygenerovat bezpečné heslo není příliš obtížné. Obtížné ovšem je si ho zapamatovat. Dnes si ukážeme způsob, jak generovat bezpečná a přitom relativně zapamatovatelná hesla.

Bezpečné heslo musí splňovat několik předpokladů. Musí být jednak rozumně dlouhé, tedy obvykle kolem deseti znaků. Nemělo by být tvořeno jedním slovem (dávajícím smysl), abychom omezili možnost slovníkového útoku. Obvykle se ještě udává, že by mělo heslo obsahovat i číslice, střídání malých a velkých písmen a případně ještě některý další neobvyklý znak jako je dolar, zavináč a podobně.

Podobná hesla obvykle dostanete vygenerovaná od rozličných systémů při registraci na webových službách, jako hesla pro přihlášení do sítě a podobně. Bohužel je problém v tom, že takové heslo si málokdo zapamatuje, uživatelé si je píší na spodek podložky pod myš či přímo na monitor a na další obskurní místa a veškerá bezpečnost je pak v tahu.

Ukážeme si dnes jedno možné řešení. Sice poněkud primitivní, nicméně může pomoct. Vtip spočívá v tom, že sice budeme generovat hesla náhodně, ovšem té náhodě malinko pomůžeme a sice tím, že budeme střídat souhlásky a samohlásky. Ať se to zdá jak chce podivné, takové heslo, byť složené stále z náhodných znaků, je daleko lépe zapamatovatelné protože "zní" jako opravdové slovo.

Vzhůru do programování. Formulář bude tentokrát velmi jednoduchý, bude obsahovat jen tlačítko, dva Editboxy a Label. Funkce na generování hesla bude "pověšená" na událost OnClick tlačítka, do prvního Editu uživatel vloží požadovanou délku hesla, do druhého Editu pak bude vypsáno vygenerované heslo.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function Password(n: integer): string;
const
  souhl: array [0..19] of Char = (`b`, `c`, `d`, `f`, `g`, `h`, `j`, `k`, `l`, `m`, `n`, `p`, `r`, `s`, `t`, `v`, `w`, `x`, `y`, `z`);
  samohl: array [0..4] of Char = (`a`, `e`, `i`, `o`, `u`);
var
  i, k: Integer;
  hlaska: boolean;
begin
  result := ``;
  hlaska := true;
  randomize;
  k := random(99);
  if k < 10 then n := n - 1
            else n := n - 2;
  for i := 1 to n do
  begin
    if hlaska then
                begin
                  result := result + souhl[random(19)];
                  hlaska := not hlaska;
                end
              else
                begin
                  result := result + samohl[random(4)];
                  hlaska := not hlaska;
                end;
  end;
  result := result + IntToStr(k);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit2.Text := Password(StrToInt(Edit1.Text));
end;

end.

Samotná funkce je pak velmi jednoduchá. Znaky si rozdělíme na souhlásky a samohlásky do dvou polí. Výjimku tvoří ypsilon, které je zařazeno do souhlásek. V cyklu poté střídavě vybíráme náhodně znaky z obou polí, čímž získáme požadované heslo. Pro drobné zvýšení bezpečnosti pak ještě na konec přidáme náhodně vygenerované číslo.

Je pravda, že bezpečnost takového hesla je pak pochopitelně menší, protože případný útočník má usnadněné hádání tím, že každý druhý znak je generován jen z malé množiny samohlásek. To lze do jisté míry kompenzovat větší délkou hesla, protože je lépe zapamatovatelné.

Příklad můžete ještě vylepšit, například o velká písmena. Zachováte-li však základní princip střídání souhlásek a samohlásek, bude heslo daleko lépe zapamatovatelné než, směsice zcela náhodných znaků. Jako obvykle si můžete stáhnout ukázkový projekt zde.