Kaikki oikeudet tietenkin pidätetään. Viimeinen versio ohjelmasta löytyy seuraavasta linkistä: moijari.com:5002. Ressu satunnaislukuja löytyy osoitteesta: moijari.com:5001. Ikuinen kalenteri osoitteesta: moijari.com:5003.
Salasana on salakirjoitettuna muodossa:
sha256:ee84f5affcf47d:51567b8c4c20db2a00ea24eaae125a26f5c7c87fdbe5b90a02225fc97008b49a (oheinen salasana on muuten "SalaSana1234") ja vielä unsigned char *peppper="l7IKrgcLMgsl_4Wv";
Alussa salatun salasanan tallennusformaatti, kaksoispisteen jälkeen alkaa salt:ti ja seuraavan kaksoispisteen jälkeen alkaa kryptattu salasana.
Tämä ensimmäinen rutiini salakirjoittaa password kentässä olevan salasanan ja muodostaa encpasswd kentän joka sisältää salasanan salakirjoitetussa muodossa.
int encryptpasswd(unsigned char encpasswd[ENCPASSWD_SIZE],unsigned char *password)
{
int c,d;
HashCtx ctx;
unsigned char salt[7];
unsigned char salthex[15];
unsigned char twodigit[3];
unsigned char temp[HashLen];
unsigned char temphex[HashLen*2+1];
memset(encpasswd,0,ENCPASSWD_SIZE);
ressu_genbytes2(sizeof(salt),salt);
...
Ohjelman alussa varataan erilaisia ohjelman tarvitsemia muistialueita. Salt kentän tarkoituksena on erilaistaa sama salasana eri käyttäjillä ja vaikeuttaa kryptattujen salasanojen hakemiston muodostamista. Salt on salakirjoittamattomana salakirjoitetussa salasanassa , ja kopioidaan sellaisenaan salasanan tarkastukseen. Temp kenttää taas käytetään kryptatun salasanan tallettamiseen..
Seuraavat ohjelmarivit muuttavat salt:in heksamuotoon:
...
for(c=0;c<sizeof(salt);c++) {
sprintf(twodigit,"%02x",salt[c]);
strcat(salthex,twodigit);
}
...
Seuraava kappale tekee varsinaisen salakirjoituksen, Salakirjoitus tehdään sha256 tiivisterutiinilla. HASHROUNDS on tällä hetkellä sata tuhatta, ja siihen on valittu mahdollisimman suuri luku, joka silti pitää logon-vaiheen keston kohtuullisena. Pepper on aloitusarvo rutiinille.
...
memset(temp,0,sizeof(temp));
strcpy(temp,pepper);
for(c=0;c<HASHROUNDS;c++) {
HashInit(&ctx);
HashUpdate(&ctx,temp,sizeof(temp));
HashUpdate(&ctx,salt,sizeof(salt));
HashUpdate(&ctx,password,strlen(password)+1);
HashFinal(temp,&ctx);
}
...
Seuraavassa edellisen koodikappaleen tulos temp muuttujassa laitetaan heksamuotoon:
...
temphex[0]='\0';
for(c=0;c<sizeof(temp);c++) {
sprintf(twodigit,"%02x",temp[c]);
strcat(temphex,twodigit);
}
...
Kootaan salakirjoitettu salasana:
... strcpy(encpasswd,"sha256:"); strcat(encpasswd,salthex); strcat(encpasswd,":"); strcat(encpasswd,temphex); ...
Ja tyhjennetään vielä välikentät, jottei niitä vuoda ulos aliohjelmasta: ja funktion lopussa vielä return lause (0=ok).
... memset(salt,0,sizeof(salt)); memset(salthex,0,sizeof(salthex)); memset(temp,0,sizeof(temp)); memset(temphex,0,sizeof(temphex)); return(0); }
Salasanan tarkistus funktio tekee oikeastaan samat asiat, hieman muuteltuna: koodikappaleen loppu tarkistaa salakirjoitetun salasanan tallennusformaatin ja hakee salt:in heksamuodossa. Salt haetaan parametrina annetusta salakirjoitetusta salasanasta.
int checkpasswd(unsigned char encpasswd[ENCPASSWD_SIZE],unsigned char *password)
{
int c,d,e,byte,ok;
unsigned char *p,*s;
HashCtx ctx;
unsigned char salt[7];
unsigned char salthex[15];
unsigned char twodigit[3];
unsigned char temp[HashLen];
unsigned char temphex[HashLen*2+1];
unsigned char encpasswd2[128];
p=encpasswd;
if(strncmp(p,"sha256:",7))
return(1);
p+=7;
s=salthex;
while(*p!=':') {
*s++=*p++;
}
*s='\0';
...
Salasanan tarkistusrutiini hakee saltin satunnaisbittigeneraattorin sijasta annetusta salakirjoitetusta salasanasta.
Seuraava siirtää heksana olevan saltin binäärimuotoon:
...
c=0;
s=salthex;
for(;;) {
if((d=gethexdigit(*s++))==-1) break;
if((e=gethexdigit(*s++))==-1) break;
byte=d*16+e;
salt[c++]=byte;
}
...
Varsinainen salasanan kryptausosa on samanlainen kun edellisessä crypt rutiinissa:
...
memset(temp,0,sizeof(temp));
strcpy(temp,pepper);
for(c=0;c<HASHROUNDS;c++) {
HashInit(&ctx);
HashUpdate(&ctx,temp,sizeof(temp));
HashUpdate(&ctx,salt,sizeof(salt));
HashUpdate(&ctx,password,strlen(password)+1);
HashFinal(temp,&ctx);
}
...
Muokanaan salakirjoitettu salasana temp kentästä temphex kenttään heksamuotoon:
...
temphex[0]='\0';
for(c=0;c<sizeof(temp);c++) {
sprintf(twodigit,"%02x",temp[c]);
strcat(temphex,twodigit);
}
...
Muodostetaan varsinainen salasana salakirjoitetussa muodossa:
... strcpy(encpasswd2,"sha256:"); strcat(encpasswd2,salthex); strcat(encpasswd2,":"); strcat(encpasswd2,temphex); ...
Vertaillaan salakirjoitettuna annettua salasanaa ja selväkielisestä salasanasta muodostettua salakirjoitettua salasanaa keskenään, tyhjennellään kenttiä ja palautetaan totuusarvo:
...
if(!strcmp(encpasswd,encpasswd2)) {
fprintf(stdout,"\n*************ok");
ok=0;
} else {
fprintf(stdout,"\n*************error");
ok=1;
}
memset(encpasswd2,0,ENCPASSWD_SIZE);
memset(salt,0,sizeof(salt));
memset(salthex,0,sizeof(salthex));
memset(temp,0,sizeof(temp));
memset(temphex,0,sizeof(temphex));
return(ok);
}
Tässä vielä gethexdigit:
int gethexdigit(char h)
{
int byte;
if(h>='0' && h<='9')
byte=h-'0';
else if(h>='a' && h<='f')
byte=h-'a'+10;
else if(h>='A' && h<='F')
byte=h-'A'+10;
else
byte=-1;
return(byte);
}