Ο agmarios δεν έχει κι άδικο. Το .NET περιλαμβάνει έτοιμους αλγόριθμους όπως TripleDES και το στάνταρ AES (αν και το ονομάζει Rijndael). Επειδή όμως οι κλάσεις των αλγορίθμων είναι για γενική χρήση, η χρήση τους για string encryption είναι λίγο περίεργη. Από την άλλη, έτσι και γράψει κανείς μία φορά τις συναρτήσεις για encrypt/decrypt, μπορεί να τις χρησιμοποιήσει όπου θέλει. Πραγματικά, δεν υπάρχει λόγος να χρησιμοποιεί κανείς αδύναμους αλγόριθμους κρυπτογράφησης όταν μπορεί να χρησιμοποιήσει εύκολα δυνατούς και ασφαλείς αλγόριθμους.
Μία εύκολη υλοποίηση είναι η κλάση Encryption64 που περιγράφεται στο http://www.devcity.net/Articles/47/1/encrypt_querystring.aspx . Η κλάση αυτή χρησιμοποιεί τον αλγόριθμο DES για να κρυπτογραφήσει strings, ο οποίος όμως θεωρείται ανασφαλής. Αλλάζοντας απλά την κλάση DESCryptoServiceProvider με την RijndaelManaged, η κλάση μπορεί να χρησιμοποιήσει τον αλγόριθμο AES (Rijndael). Ο τροποποιημένος κώδικας είναι ο εξής:
Imports System
Imports System.IO
Imports System.Xml
Imports System.Text
Imports System.Security.Cryptography
Imports NUnit.Framework
Public Class Encryption64
Private key() As Byte = {}
Private IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF, &H1A, &H2B, &H3C, &H4D, &H5E, &H6F, &H70, &HA1}
Public Function Decrypt(ByVal stringToDecrypt As String, _
ByVal sEncryptionKey As String) As String
Dim inputByteArray(stringToDecrypt.Length) As Byte
key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
Dim crypto As New RijndaelManaged()
inputByteArray = Convert.FromBase64String(stringToDecrypt)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, crypto.CreateDecryptor(key, IV), _
CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
Return encoding.GetString(ms.ToArray())
End Function
Public Function Encrypt(ByVal stringToEncrypt As String, _
ByVal SEncryptionKey As String) As String
key = System.Text.Encoding.UTF8.GetBytes(Left(SEncryptionKey, 8))
Dim crypto As New RijndaelManaged()
Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes( _
stringToEncrypt)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, crypto.CreateEncryptor(key, IV), _
CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Return Convert.ToBase64String(ms.ToArray())
End Function
End Class
Και ένα παράδειγμα χρήσης:
Dim encrypter As New Encryption64
Dim clearText As String = "Hello World!"
Dim encryptedString = encrypter.Encrypt(clearText, "MyPassword")
Dim decryptedString = encrypter.Decrypt(encryptedString, "MyPassword")
Εδώ χρειάζονται και λίγες εξηγήσεις για το τί είναι IV. Οι ισχυροί αλγόριθμοι κρυπτογράφησης δουλεύουν επάνω σε block από δεδομένα αντί για ένα-ένα byte. Το κάθε block που κρυπτογραφείται χρησιμοποιείται σαν βάση για την κρυπτογράφηση του επόμενου block. Αυτό όμως σημαίνει ότι κάπου πρέπει να δωθεί το πρώτο "κρυπτογραφημένο" block. Αυτός είναι ο ρόλος του IV (initialization vector) το οποίο καλό θα είναι να αποτελείται από τυχαία νούμερα. Στο παραπάνω παράδειγμα τα νούμερα δεν είναι και πολύ τυχαία, αλλά ο καθένας μπορεί να τα αλλάξει. Τέλος, για καλύτερη ασφάλεια δεν χρησιμοποιούμε το ίδιο το κλειδί αλλά μία μορφή του που έχει γίνει hash μερικές δεκάδες φορές.
Ευτυχώς, έτσι και γράψεις μία φορά μια κλάση όπως η Encryption64 δεν χρειάζεται να ασχοληθείς ξανά με τις λεπτομέρειες υλοποίησης. Μπορείς έτσι με δύο γραμμές κώδικα, την Encrypt και την Decrypt να έχεις όσο δυνατή κρυπτογράφηση θέλεις.
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos