Satt och skulle bygga lite verktyg för att hålla reda på lösenord och inloggningar internt för Centrum för Effektivt IT, och så tittade jag på en serie om AES kryptering som fans på youtube för att fräscha up mina kunskaper. Kan rekommendera dessa Townsend Intro to AES, det fanns avancerade också från samma person/företag.
I vilket fall så nämnde han något jag inte tänkt på förut och det var: Hur vet man att ingen ändrat på den krypterade datan?
Jag menar de behöver kanske inte alltid ha knäckt krypteringen för att ställa till stora problem för programmet som skall använda denna krypterade data. Det kan ju räcka att lite i den krypterade strängen för att en mjukvara inte skall finna vad den förvänta sig och därmed flippa ut och skapa säkerhetsproblem eller bara vara till besvär. Det han nämnde var att använda hash för att verifiera sin data.
Så jag byggde två funktioner i Pascal
Pascal: Jo jag vet, folk tycker det är utdött, och jag programmerar till vardags i nästan alla språk men jag älskar pascal och jag var så oerhört glad att se att free-pascal och Lazarus har kommit så långt i sin utveckling att det är riktigt användbart. Jag har inte haft några problem att kompilera om mina gamla utils sedan förr (Delphi) i både Windows och Linux vilket är hur coolt som helst och betydligt mindre overhead än att använda java.
Tillbaks till den egentliga diskussionen.
Funktionen nedan tar en sträng som den lägger till en sha256 hash i slutet på och krypterar.
1: function EncryptString(source: String): String;
2: begin
3: Cipher:= TDCP_rijndael.Create(nil);
4: Cipher.InitStr(sha256hash(key),TDCP_sha256);
5: // Notera att jag nedan lägger till en hash av
6: // source till strängen innan krypteringen
7: source := source +'#'+sha256hash(source);
8: Result:=Cipher.EncryptString(source);
9: Cipher.Burn;
10: Cipher.Free;
11: end;
Denna motsatta funktion tar en krypterad sträng och avkrypterar den upp den, sedan delar den på hash och värde, gör en ny hash av värdet och jämför de två hasharna. Om dessa är lika då godkänner den resultatet annars returneras “ERROR (Data integrity)”.
1: function DecryptString(source: String): String;
2: var
3: i, i2:Integer;
4: tmpStr,tmpHash:String;
5: begin
6: Cipher:= TDCP_rijndael.Create(nil);
7: Cipher.InitStr(sha256hash(key),TDCP_sha256);
8: tmpStr:=Cipher.DecryptString(source);
9: tmpHash:=copy(tmpStr,Rpos('#',tmpStr)+1,UTF8Length(tmpStr)-Rpos('#',tmpStr));
10: tmpStr:=copy(tmpStr,0,Rpos('#',tmpStr)-1);
11: if (tmpHash = sha256hash(tmpStr)) then Result:=tmpStr else Result := 'ERROR (Data integrity)';
12: Cipher.Burn;
13: Cipher.Free;
14: end;
Eventuellt skulle man skapa en riktig error, men för mitt behov är detta bättre och jag kollar efter ERROR när jag använder funktionen.
I vilket fall så genom att göra så här så ökar man säkerheten och blir medveten om ifall någon ändrat på den krypterade data man lagrat.
c19c0704-252c-4605-84db-31ada232ac99|0|.0