Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
The Autenticator - Autenticator.vb

Autenticator.vb

Caricato da: Totem
Scarica il programma completo

  1. Imports System.Security.Cryptography
  2. ''' <summary>
  3. ''' Questa classe deve essere tenuta nascosta. Serve per generare un codice
  4. ''' dato un nome utente.
  5. ''' </summary>
  6. Public Class CodeGenerator
  7.     Private _UserName As String
  8.     Private _CodeLength As Int16 = 16
  9.     Private _DerivingIterations As Int16 = 5
  10.     Private _SaltBytes As Byte()
  11.     Private _Code As String
  12.  
  13.     ''' <summary>
  14.     ''' Nome utente da usare. Ad un nome utente sarà associato un solo codice.
  15.     ''' </summary>
  16.     Public Property UserName() As String
  17.         Get
  18.             Return _UserName
  19.         End Get
  20.         Set(ByVal value As String)
  21.             _UserName = value
  22.             _Code = Nothing
  23.         End Set
  24.     End Property
  25.  
  26.     ''' <summary>
  27.     ''' Lunghezza del codice generato, in bytes. Dato che il codice viene scritto in esadecimale,
  28.     ''' ad ogni bytes corrispondono due cifre. Perciò il codice finale avrà lunghezza doppia.
  29.     ''' </summary>
  30.     Public Property CodeLength() As Int16
  31.         Get
  32.             Return _CodeLength
  33.         End Get
  34.         Set(ByVal value As Int16)
  35.             If value >= 8 Then
  36.                 _CodeLength = value
  37.             Else
  38.                 _CodeLength = 8
  39.             End If
  40.             _Code = Nothing
  41.         End Set
  42.     End Property
  43.  
  44.     ''' <summary>
  45.     ''' Salt crittografico. Questo array di bytes viene usato per derivare il codice finito.
  46.     ''' E' il punto di forza dell'algoritmo, in quanto ogni programmatore che usa questa classe
  47.     ''' può utilizzare un array di bytes diverso da tutti gli altri, e ciò produrra anche un
  48.     ''' risultato diverso. Questo sorgente, quindi, è riusabile al 100%.
  49.     ''' </summary>
  50.     Public Property SaltBytes() As Byte()
  51.         Get
  52.             Return _SaltBytes
  53.         End Get
  54.         Set(ByVal value As Byte())
  55.             _SaltBytes = value
  56.             _Code = Nothing
  57.         End Set
  58.     End Property
  59.  
  60.     ''' <summary>
  61.     ''' Numero di iterazioni compiute dall'algoritmo di derivazione. Anche questo è un fattore
  62.     ''' cambiando il quale cambia il risultato.
  63.     ''' </summary>
  64.     Public Property DerivingIterations() As Int16
  65.         Get
  66.             Return _DerivingIterations
  67.         End Get
  68.         Set(ByVal value As Int16)
  69.             If value >= 2 Then
  70.                 _DerivingIterations = value
  71.             Else
  72.                 _DerivingIterations = 2
  73.             End If
  74.             _Code = Nothing
  75.         End Set
  76.     End Property
  77.  
  78.     ''' <summary>
  79.     ''' Code generato alla fine del procedimento.
  80.     ''' </summary>
  81.     Public ReadOnly Property Code() As String
  82.         Get
  83.             If _Code Is Nothing Then
  84.                 Me.CalculateCode()
  85.             End If
  86.  
  87.             Return _Code
  88.         End Get
  89.     End Property
  90.  
  91.     'Trovate una spiegazione breve dell'algoritmo di derivazione sulla mia guida
  92.     Private Sub CalculateCode()
  93.         Dim Derive As Rfc2898DeriveBytes
  94.         Dim DerivedBytes() As Byte
  95.         Dim Result As New System.Text.StringBuilder
  96.  
  97.         Derive = New Rfc2898DeriveBytes(Me.UserName, SaltBytes, Me.DerivingIterations)
  98.         DerivedBytes = Derive.GetBytes(Me.CodeLength)
  99.  
  100.         For I As Int16 = 0 To Me.CodeLength - 1
  101.             Result.AppendFormat("{0:X2}", DerivedBytes(I))
  102.         Next
  103.  
  104.         _Code = Result.ToString
  105.     End Sub
  106.  
  107.     ''' <summary>
  108.     ''' Divide il codice generato in blocchi più piccoli da X caratteri ciascuno.
  109.     ''' </summary>
  110.     ''' <param name="Separator">Stringa da inserire tra ciascun blocco.</param>
  111.     ''' <param name="ByteCounts">Questo array contiene la numerosità di ciascun blocco.</param>
  112.     ''' <remarks>Se ad esempio, si ha il codice "AB4F89D" e si imposta Seperator="-" e
  113.     ''' ByteCounts su {1,3,3}, si otterrà la stringa "A-B4F-89D".</remarks>
  114.     Public Function GetFormattedCode(ByVal Separator As String, ByVal ParamArray ByteCounts As Int16()) As String
  115.         Dim CodeReader As New IO.StringReader(Me.Code)
  116.         Dim Buffer() As Char
  117.         Dim Result As New System.Text.StringBuilder
  118.  
  119.         For I As Int16 = 0 To ByteCounts.Length - 1
  120.             ReDim Buffer(ByteCounts(I) - 1)
  121.             CodeReader.ReadBlock(Buffer, 0, ByteCounts(I))
  122.             Result.Append(Buffer)
  123.  
  124.             If I < ByteCounts.Length - 1 Then
  125.                 Result.Append(Separator)
  126.             End If
  127.         Next
  128.  
  129.         Return Result.ToString
  130.     End Function
  131. End Class
  132.  
  133. 'Esempio
  134. Module AutenticationModule
  135.     Sub Main()
  136.         Dim C As New CodeGenerator
  137.  
  138.         '8 bytes -> 16 caratteri
  139.         C.CodeLength = 8
  140.         'Array di bytes assolutamente casuali: vedrete che anche cambiando di 1
  141.         'l'ultimo byte si otterrà un codice completamente diverso.
  142.         C.SaltBytes = New Byte() {90, 2, 189, 250, 78, 3, 12, 67}
  143.  
  144.         'Legge l'UserName
  145.         Console.Write("UserName = ")
  146.         C.UserName = Console.ReadLine
  147.  
  148.         'Scrive il codice generato, formattato in questo modo:
  149.         'XXXX - XXXX - XXXX - XXXX
  150.         Console.Write("Code = {0}", C.GetFormattedCode(" - ", 4, 4, 4, 4))
  151.  
  152.         Console.ReadKey()
  153.     End Sub
  154. End Module