Page 1 of 1

Mã hoá/Giải mã tập tin theo kiểu bảo mật cao

Posted: Fri 28/03/2008 10:57 pm
by duyluandethuong
Tên bài viết: Mã hoá/Giải mã tập tin theo kiểu bảo mật cao
Tác giả: vo_minhdat2007
Cấp độ bài viết: Chưa đánh giá
Tóm tắt: Mã hoá/Giải mã tập tin theo kiểu bảo mật cao


Như các bạn đã biết là có rất nhiều cách mã hoá như String, Long, … . Nhưng trong đó bảo mật chưa cao, và như String thì các kí tự Unicode sau khi mã hoá và giải mã chỉ còn là những dấu ?. Vậy có cách nào không? Câu trả lời là có. Bữa nay dài dòng văn vẻ chút :-D . Ngoài ra đừng trách em dài dòng, em muốn chỉ cơ bản cho newbie luôn.
Thêm các lệnh Import :
Thêm các lệnh Import luônở trên đầu tất cả, kể cả lệnh của class Module, nói tóm lại là không còn gì ở trên nó được :

1. Imports System
2. Imports System.IO
3. Imports System.Security
4. Imports System.Security.Cryptography
5. Imports System.Runtime.InteropServices
6. Imports System.Text

Các phương thức mã hoá/giải mã :
Có 2 phương thức chủ yếu, à không trong bài này chỉ có 2 phương thức này :-D :
- Phương thức 1: Bạn có thể hỏi mật khẩu từ người dùng và lấy nó để tạo khoá.
- Phương thức 2 : Tạo một khoá từ máy (tất nhiên bảo mật cao).
Cách lấy khoá :
Nếu dùng phương thức 2, bạn cần 2 hàm sau :

Code: Select all

  1. 'Gọi cái này để xoá khoá khỏi bộ nhớ : bảo mật
  2. Private Declare Sub ZeroMemory Lib "kernel32.dll" Alias "RtlZeroMemory" _
  3.     (ByVal Destination As String, ByVal Length As Integer)
  4. 'Hàm tạo khoá :
  5. Function GenerateKey() As String
  6. Dim desCrypto As DESCryptoServiceProvider = DESCryptoServiceProvider.Create()
  7. Return ASCIIEncoding.ASCII.GetString(desCrypto.Key)
  8.    End Function


Mã hoá/Giải mã tập tin :
Đây là phần chính nè :
1. Tạo Sub (hoặc Function) mã hoá :
Bạn khai báo gồm 3 tham số :

1. sInputFile : tập tin đọc vào cần mã hoá.
2. sOutputFile : tập tin ghi ra sau khi mã hoá
3. sKey : Mã khoá đã tạo hoặc hỏi, nói tóm lại là đoạn String bất kì, nhưng nhớ là mã hoá sao là phải giải mã đúng khoá như vậy.

Bây giờ, để đọc ghi thì nên chọn phương pháp sử dụng StreamReader và StreamWrite. Khai báo thế này :

Code: Select all

  1. Dim fsInput As New FileStream(sInputFilename, _
  2. FileMode.Open, FileAccess.Read)
  3. Dim fsEncrypted As New FileStream(sOutputFilename, _
  4. FileMode.Create, FileAccess.Write)


Tất nhiên là bạn cần 1 lớp (class) DESCryptoServiceProvider rồi. Công dụng của class này nói nôm na là để thể hiện sự mã hoá và giải mã.

Code: Select all

  1. Dim DES As New DESCryptoServiceProvider()



Tiếp theo là bạn dùng GetByte() và mã hoá chúng nhé. Nếu ai cần tìm hiểu thêm về GetByte xin liên hệ các MOD của .NET, còn mình còn non lắm, giải thích chắc không ai hiểu :-D . Tóm lại bạn tham khảo đoạn code sau :

Code: Select all

  1. DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey)
  2. DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey)


Bây giờ bạn tạo một lớp CryptoStream. Dùng mật khẩu cung cấp để lấy được một đối tượng mã hoá (CreateEncryptor).

Code: Select all

  1. Dim cryptostream As New CryptoStream(fsEncrypted,
  2.     desencrypt, CryptoStreamMode.Write)


Việc còn lại khá đơn giản, đọc từ tập tin vào và đưa ra tập tin đích. Dim [code=vb.net]bytearrayinput(fsInput.Length - 1) As Byte
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length)
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length)[/code]
Tóm lại, ta có một Sub mã hoá như sau :

Code: Select all

  1. Sub EncryptFile(ByVal sInputFilename As String, _
  2.                   ByVal sOutputFilename As String, _
  3.                   ByVal sKey As String)
  4.  
  5.       Dim fsInput As New FileStream(sInputFilename, _
  6.                                   FileMode.Open, FileAccess.Read)
  7.       Dim fsEncrypted As New FileStream(sOutputFilename, _
  8.                                   FileMode.Create, FileAccess.Write)
  9.  
  10.       Dim DES As New DESCryptoServiceProvider()
  11.  
  12.       'Set secret key for DES algorithm.
  13.       'A 64-bit key and an IV are required for this provider.
  14.       DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey)
  15.  
  16.       'Set the initialization vector.
  17.       DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey)
  18.  
  19.       'Create the DES encryptor from this instance.
  20.       Dim desencrypt As ICryptoTransform = DES.CreateEncryptor()
  21.       'Create the crypto stream that transforms the file stream by using DES encryption.
  22.       Dim cryptostream As New CryptoStream(fsEncrypted, _
  23.                                           desencrypt, _
  24.                                           CryptoStreamMode.Write)
  25.  
  26.       'Read the file text to the byte array.
  27.       Dim bytearrayinput(fsInput.Length - 1) As Byte
  28.       fsInput.Read(bytearrayinput, 0, bytearrayinput.Length)
  29.       'Write out the DES encrypted file.
  30.       cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length)
  31.       cryptostream.Close()
  32.    End Sub


Sub (hoặc Function) giải mã
Đã mã hoá tất nhiên phải giải mã được rồi (không thì chết :-D ), tất nhiên như đã nói, keygiải mã = keymã hoá. Tham khảo code sau nhé:

Code: Select all

  1. Sub DecryptFile(ByVal sInputFilename As String, _
  2.        ByVal sOutputFilename As String, _
  3.        ByVal sKey As String)
  4.  
  5.       Dim DES As New DESCryptoServiceProvider()
  6.       'A 64-bit key and an IV are required for this provider.
  7.       'Set the secret key for the DES algorithm.
  8.       DES.Key() = ASCIIEncoding.ASCII.GetBytes(sKey)
  9.       'Set the initialization vector.
  10.       DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey)
  11.  
  12.       'Create the file stream to read the encrypted file back.
  13.       Dim fsread As New FileStream(sInputFilename, FileMode.Open, FileAccess.Read)
  14.       'Create the DES decryptor from the DES instance.
  15.       Dim desdecrypt As ICryptoTransform = DES.CreateDecryptor()
  16.       'Create the crypto stream set to read and to do a DES decryption transform on incoming bytes.
  17.       Dim cryptostreamDecr As New CryptoStream(fsread, desdecrypt, CryptoStreamMode.Read)
  18.       'Print out the contents of the decrypted file.
  19.       Dim fsDecrypted As New StreamWriter(sOutputFilename)
  20.       fsDecrypted.Write(New StreamReader(cryptostreamDecr).ReadToEnd)
  21.       fsDecrypted.Flush()
  22.       fsDecrypted.Close()
  23.    End Sub


Gọi các Sub hoặc Function đã tạo
Tiếp theo để gọi các lệnh mã hoá và giải mã bạn làm như sau :

Code: Select all

  1. 'Must be 64 bits, 8 bytes.
  2.       Dim sSecretKey As String
  3.  
  4.       ' Get the key for the file to encrypt.
  5.       ' You can distribute this key to the user who will decrypt the file.
  6.       sSecretKey = GenerateKey()
  7.  
  8.       ' For additional security, pin the key.
  9.       Dim gch As GCHandle = GCHandle.Alloc(sSecretKey, GCHandleType.Pinned)
  10.  
  11.  
  12.       ' Encrypt the file.        
  13.       EncryptFile("%USERPROFILE%\MyData.txt", _
  14.                       "%USERPROFILE%\Encrypted.txt", _
  15.                       sSecretKey)
  16.  
  17.       ' Decrypt the file.
  18.       DecryptFile("%USERPROFILE%\Encrypted.txt", _
  19.                   "%USERPROFILE%\Decrypted.txt", _
  20.                   sSecretKey)
  21.  
  22.       ' Remove the key from memory.
  23.       ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2)
  24.       gch.Free()

Re: Mã hoá/Giải mã tập tin theo kiểu bảo mật cao

Posted: Wed 05/11/2008 2:23 pm
by xuanquy_th
Thế này có mà đứt.

Re: Mã hoá/Giải mã tập tin theo kiểu bảo mật cao

Posted: Fri 22/05/2009 7:03 pm
by vo_minhdat2007
Thay toàn bộ ASCII trong code trên thành Unicode để không bị như vậy!

Re: Mã hoá/Giải mã tập tin theo kiểu bảo mật cao

Posted: Wed 30/09/2009 3:53 pm
by tieuthienma
Xin chào anh !

Em đọc bài viết của anh và em thấy rất hay không biết anh có thể cho em xin một cái source để tham khảo không ạ :( , vì em code toàn bị báo lỗi :-S

Cám ơn anh trước !

Re: Mã hoá/Giải mã tập tin theo kiểu bảo mật cao

Posted: Tue 10/08/2010 2:13 pm
by xuanquy_th
Thay toàn bộ ASCII trong code trên thành Unicode để không bị như vậy!

Có cách nào không cần làm công đoạn này không nhỉ???

Như VD test ở trên có thay thế vẩn không đạt được mục đích.