Wachtwoord-check
Crypt
Er bestaat een Gambas bibliotheek (component) voor wachtwoord versleuteling en checken van een wachtwoord:
Crypt
De Crypt klasse levert : Check DES MD5 SHA256 SHA512
Hiermee kan je een wachtwoord versleutelen met DES of MD5, algoritmes uit de GNU libc bibliotheek.
ps: Zoals in Linux gebruikt, op de commandolijn met md5sum abc.txt om de checksum van (download) bestand abc.txt te krijgen.
Je kan ook de checksum van een gegeven wachtwoord vergelijken met de opgeslagen checksum van een eerder gegeven wachtwoord (waarbij je dat origineel wachtwoord niet opslaat, maar enkel de checksum); als die klopt is het gegeven wachtwoord juist.
Versleutel-ontsleutel
OpenSSL
Er is ook een bibliotheek die toelaat tekst te versleutelen en ontsleutelen (IDE-menu Project, Properties, Components): gb.openssl
OpenSSL levert:
Cipher
de cipher (block en stream) algoritmes van OpenSSL. Wikipedia: Ciphers.CipherText
Digest
de hash algoritmes van het OpenSSL project. Wikipedia: Cryptographic hash functionHMac
op hash gebaseerde berichten-toegangscodering (HMAC). Wikipedia: HMAC
Algoritmes
Er bestaan verschillende versleutelalgoritmes (en “operation modes”), en je kan die na het kiezen van de openssl library ook opvragen.
Maak een nieuw leeg project in Gambas3 (misschien werkt het ook in 2), en in de MMain vul je onderstaande code in.
Die toont op de commandolijn alle aanwezige algoritmes, en bewaart ze ook in een bestand (~/.config/gambas3/CipherList.conf
)
CipherList
Private sName As String Private icount As Integer Public Sub Main() Settings["Cipher/date"] = Str$(Now()) For Each sname In Cipher.List.Sort() Print sName; "\n"; Settings["Cipher/" & Str$(icount)] = sName Inc icount Next End
Je krijgt een lijst van bv 89 mogelijkheden (zie lijst onderaan); ze bestaan uit de encryptiemethode (plus bit-sterkte) en een “mode”, bv CBC staat voor Cipher Block Chaining (zie hieronder “operation mode” *).
Enkele algoritmen uit de lijst:
AES-128-CBC
staat eerste in de lijst, gebruikt in dit vb.- BlowFish (Schneier) is veelgebruikt, maar ondertussen door hem als verouderd beschouwd (zie twofish).
- DES=Data Encryption Standard: werd bekend om zijn korte sleutel, gedeeltelijke geheimhouding en betrokkenheid van NSA.
- AES=Advanced Encryption Standard: Rijndael (ontwikkeld door twee Belgen: V. Rijmen & J. Daemen): opvolger van DES (Amerikaanse standaard). AES-128 wordt nog steeds als veilig gezien (2006).
- , en spijtig genoeg niet in de lijst: twofish.
Je hebt de letterlijke tekstwaarde van de gekozen methode nodig om het algoritme op te roepen in je programma.
* Operation mode
Bepaalt op welke manier het oorspronkelijk te versleutelen bericht benaderd wordt voor versleuteling.
De “mode” wordt aangegeven door de extra lettercombinatie achteraan:
- ECB=Electronic CodeBook: bericht wordt in stukjes gekapt, elk stuk versleuteld. Zwakte: patronen worden zichtbaar! (vgl elke letter apart versleutelen; patroon van de “e” wordt zichtbaar)
- * CBC=Cipher Block Chaining: er wordt op iedere blok een bewerking gedaan tov het vorige blok, en een initialisatie vector moet gebruikt worden voor het eerste blok. De-cryptie kan parrallel, en Random Read Acces is mogelijk.
- * CTR=CounTeR of ICM=Integer Counter Mode of SIC=Segmented Integer Counter: maakt van een block cipher een stream cipher. En+De-cryptie kan parrallel, en Random Read Acces is mogelijk.
- PCBC=Propagating Cipher Block Chaining: gebruikt ook initialisatievector.
- CFB=Cipher Feedback
* aanbevolen methode door o.a. Bruce Schneier (van Schneier on Security)
Meer info zie wikipedia Block_cipher_mode_of_operation
Tekst versleutelen – ontsleutelen
Het volgende stukje programma kan je toevoegen aan het vorige, het geeft een encryptie en decryptie van “Geheim”:
Print Cipher["AES-128-CBC"].Encrypt("Geheim") Print Cipher["AES-128-CBC"].Decrypt(Cipher["AES-128-CBC"].Encrypt("Geheim"))
Het resultaat:
(CipherText 0x1ce7cf8)
Geheim
Meestal zal je de encrypt en decrypt niet in één regel gebruiken, en gebruik je een variabele, en dat is hier geen eenvoudige tekst (string).
Om die te declareren heb je de speciale variabele uit Cipher nodig:
Private hEncrypted As CipherText
En de code met encrypt naar variabele, en apart decrypt:
hEncrypted = Cipher["AES-128-CBC"].Encrypt("Geheim") Print hEncrypted Print Cipher["AES-128-CBC"].Decrypt(hEncrypted)
De encryptie-methode steek je in een constante, bv PRIVATE Const sEncryptmethod AS String = “AES-128-CBC”.
In de code hier net boven ontbreken trouwens nog de Key en de InitVector.
Versleutelde tekst in bestand
In het geval dat de versleutelde tekst in een bestand zit, en daarnaar geschreven + daaruit gelezen moet worden, kan het hetvolgende programma gebruiken:
' Gambas module file Private hEncrypted As CipherText Private sLine As String Private sCryptedFile As String Private Const sAlgorithm As String = "AES-128-CBC" Private sKey As String ' 32 ?? Private sInitVector As String ' 16 Public Sub Main() Print "Hello cipher world 2" ' sCryptedFile = User.Home &/ "cipher.bin" hEncrypted = Null ' can be asked from user: sKey = "123456789012345678901234567890123" sInitVector = "1234567890123ABC" Print "Geef een woord of tekst (einde met enter):" Line Input sLine Try hEncrypted = Cipher[sAlgorithm].Encrypt(sLine, sKey, sInitVector) If Error Print Error.Text & " with key " & sKey TestKeyLength() Endif File.Save(sCryptedFile, hEncrypted.Cipher) Print Base64$(File.Load(sCryptedFile)) sLine = "" Print "I Decrypt " & sCryptedFile & " as : " ' sLine = Cipher["AES-128-CBC"].Decrypt(File.Load(sCryptedFile)) ' TYPE Mismatch, wanted CipherText, got String instead ' split up: hEncrypted = New CipherText(File.Load(sCryptedFile), sKey, sInitVector) ' now it seems we have to use the key and initvector, even if not required to encrypt ... sLine = Cipher[sAlgorithm].Decrypt(hEncrypted) Print sLine End
Print Base64$
maakt het een beetje leesbaar op de console zonder dat er rare dingen gebeuren; je kan ook het bestand gaan bekijken met bv kwrite, en daar zal het er helemaal anders uitzien…
ÍÿÆ&ÜáÒ²ÆÀ9ÿáUÿ2úKüÛ
De sleutel
Het volgende probleem is: hoe bepaal je de key? Hoe lang moet die zijn? Theorie buiten beschouwing gelaten kan je het zelf uitzoeken op jouw systeem met deze proefondervindelijke methode:
Public Sub TestKeyLength() Dim sKeyShorter As String sKeyShorter = "123456789012345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ" While (Len(sKeyShorter) > 1) sKeyShorter = Left(sKeyShorter, -1) Try hEncrypted = Cipher[sAlgorithm].Encrypt(sLine, sKeyShorter, sInitVector) If Not Error Print "no error at keylength: " & Str(Len(sKeyShorter)) Exit Else Print "Err with: " & sKeyShorter & " " & Len(sKeyShorter) Endif Wend End
Het resultaat in mijn console:
Hello cipher world 2 Geef een woord of tekst (einde met enter): Gambas3 really rocks! Key length does not match method with key 1234567890123456789012345 67890123 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXY 5 5 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNOPQRSTUVWX 54 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNOPQRSTUVW 53 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNOPQRSTUV 52 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNOPQRSTU 51 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNOPQRST 50 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNOPQRS 49 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNOPQR 48 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNOPQ 47 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNOP 46 Err with: 123456789012345678901234567890ABCDEFGHIJKLMNO 45 Err with: 123456789012345678901234567890ABCDEFGHIJKLMN 44 Err with: 123456789012345678901234567890ABCDEFGHIJKLM 43 Err with: 123456789012345678901234567890ABCDEFGHIJKL 42 Err with: 123456789012345678901234567890ABCDEFGHIJK 41 Err with: 123456789012345678901234567890ABCDEFGHIJ 40 Err with: 123456789012345678901234567890ABCDEFGHI 39 Err with: 123456789012345678901234567890ABCDEFGH 38 Err with: 123456789012345678901234567890ABCDEFG 37 Err with: 123456789012345678901234567890ABCDEF 36 Err with: 123456789012345678901234567890ABCDE 35 Err with: 123456789012345678901234567890ABCD 34 Err with: 123456789012345678901234567890ABC 33 Err with: 123456789012345678901234567890AB 32 Err with: 123456789012345678901234567890A 31 Err with: 123456789012345678901234567890 30 Err with: 12345678901234567890123456789 29 Err with: 1234567890123456789012345678 28 Err with: 123456789012345678901234567 27 Err with: 12345678901234567890123456 26 Err with: 1234567890123456789012345 25 Err with: 123456789012345678901234 24 Err with: 12345678901234567890123 23 Err with: 1234567890123456789012 22 Err with: 123456789012345678901 21 Err with: 12345678901234567890 20 Err with: 1234567890123456789 19 Err with: 123456789012345678 18 Err with: 12345678901234567 17 no error at keylength: 16 gM3/gsYm3OEC0g+ygcaKwDn/4VX/Mg6GjPqQS/zblgo= I Decrypt /home/cybr/cipher.bin as : Gambas3 really rocks!
Dus in plaats van de 32 tekens voor de key, elders vermeld in literatuur, heb ik hier 16 nodig.
Ik kan aan mijn programma’s een tekstbestand leveren met een versleutelde toegangscode voor de databank.
Wie het bestand leest kan er niets mee. Wie het programma ontleedt wel als de sleutel en initvector (of salt) vast in de broncode staan.
De hele lijst van mogelijke algoritmes:
Continue reading