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); }