Generation de mots de passe, encore un mais celui là est un code de fainéant

Contenu du snippet

Comme toujours lorsqu'on a besoin d'un p'tit bout de code tout simple dont on est sur que tout le monde à développer, on cherche et on trouve mais le p'tit bout de code s'avère au final assez long et chiant à controler, eh oui faut quand même vérifier un minimum même si en apparence ça marche, bla bla bla ...

Enfin bref, voici 3 class permettant de générer proprement une chaine de caractères aléatoire.

Les 2 premières sont issues du msdn, elles portent sur la cryptographie
- cf Cryptographie simplifiée dans Microsoft .NET : Class CryptoSHA1
- cf Protection de données privées à l'aide des espaces de nom Cryptography de .NET Framework : Class CryptoRC2

La 3ème contient la fonction de génération utilisant les 2 class précédentes
- Class AutoPassword

L'astuce s'appuit sur la méthode de génération de clef et du hashage de cette dernière pour vraiment obtenir une chaine de caractère, si non vous aurez des surprises

Source / Exemple :


Imports System.Security.Cryptography

Public Class AutoPassword

    'le mot de passe est inférieur à 28 caractères car ce nombre 
    'dépend du cryptage et du hash utilisé, ici RC2 et SHA1
    'Attention le nb ici est le nombre de caractère à enlever
    'il doit donc être inférieure à 27

    Function generer(ByVal nb As Integer) As String

        Dim crypto As New CryptoRC2
        Dim hash As New CryptoSHA1
        Dim str, strFind, strReplace As String

        crypto.genererKey()
        str = hash.HashText(crypto.textConverter.GetString(crypto.key))

        ' Moi ces caractères me gène, libre à vous de les garder
        generer = Replace(str, "/", "é")
        generer = Replace(generer, "=", "ù")
        generer = Replace(generer, "+", "è")
        
        generer = generer.Remove(0, nb)

    End Function

End Class

' -------------------------------------------------------------------------------------------

Imports System
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography

Class CryptoRC2

    'Voici le textConverter nécessaire à l’encodage des différents formats:
    Public textConverter As New System.Text.ASCIIEncoding
    'On crée ensuite une instance d’un des algorithmes du Framework .Net
    Public rc2CSP As New Security.Cryptography.RC2CryptoServiceProvider
    'On crée les variables d’échange de valeurs cryptées non cryptées 
    Public fromEncrypt() As Byte
    Public encrypted() As Byte
    Public toEncrypt() As Byte
    'On crée les variables de stockage des clefs de cryptage.
    Public key() As Byte
    Public IV() As Byte

    'on génère les clefs de l'algorythme rc2 
    Public Function genererKey()
        rc2CSP.GenerateKey()
        key = rc2CSP.Key
    End Function

    Public Function genererIV()
        rc2CSP.GenerateIV()
        IV = rc2CSP.IV
    End Function

    Public Function crypter(ByVal message As String)
        'on génère un encrypteur avec les clefs que l’on a généré :
        Dim encryptor As Security.Cryptography.ICryptoTransform = rc2CSP.CreateEncryptor(key, IV)
        'on converti le texte en byte() : attention les parenthèses sont importantes, car l’encrypteur ne travaille qu’avec des flux de données et rien d’autre : 
        toEncrypt = textConverter.GetBytes(message)
        'on crypte les données 'On crée le flux de données qui recevra le message crypté :
        Dim msEncrypt As New System.IO.MemoryStream
        'On crée le flux de travail de l’encrypteur :
        Dim csEncrypt As New Security.Cryptography.CryptoStream(msEncrypt, encryptor, Security.Cryptography.CryptoStreamMode.Write)
        'Après encryptation on transfert les données cryptées dans le flux
        'Puis dans la variable d’exportation 
        csEncrypt.Write(toEncrypt, 0, toEncrypt.Length)
        csEncrypt.FlushFinalBlock()
        encrypted = msEncrypt.ToArray()
    End Function

    Public Function decrypter()
        'on crée un décrypteur qui utilise les mêmes clefs
        Dim decryptor As Security.Cryptography.ICryptoTransform = rc2CSP.CreateDecryptor(key, IV)
        'on décrypte les données 
        'notez que encrypted est chargée d’emblée dans le flux
        Dim msDecrypt As New System.IO.MemoryStream(encrypted)
        Dim csDecrypt As New Security.Cryptography.CryptoStream(msDecrypt, decryptor, Security.Cryptography.CryptoStreamMode.Read)
        fromEncrypt = New Byte(encrypted.Length) {}
        'Enfin on transfert le résultat dans fromEncrypt
        csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length)
    End Function

    Public Function traduire() As String
        'on reconvertit les données en texte. 
        traduire = textConverter.GetString(fromEncrypt)
    End Function

End Class 'CryptoRC2

' ------------------------------------------------------------------------------------------

Imports System.Security.Cryptography

Public Class CryptoSHA1

    Public Function HashText(ByVal TextToHash As String) As String

        Dim SHA1 As SHA1CryptoServiceProvider
        Dim bytValue() As Byte
        Dim bytHash() As Byte

        ' Create New Crypto Service Provider Object
        SHA1 = New SHA1CryptoServiceProvider

        ' Convert the original string to array of Bytes
        bytValue = System.Text.Encoding.UTF8.GetBytes(TextToHash)

        ' Compute the Hash, returns an array of Bytes
        bytHash = SHA1.ComputeHash(bytValue)

        SHA1.Clear()

        ' Return a base 64 encoded string of the Hash value
        HashText = Convert.ToBase64String(bytHash)

    End Function

End Class

' --------------------------------------------------------------------------------------------

' Pour utiliser au final dans votre *.aspx.vb, via un bouton et un textbox par exemple :

Imports System
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography

Public Class testGenerer

        Inherits System.Web.UI.Page
        Protected WithEvents TextBox As System.Web.UI.WebControls.TextBox
        Protected WithEvents bouton As System.Web.UI.HtmlControls.HtmlInputButton

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Placez ici le code utilisateur pour initialiser la page
End Sub
  
Private Sub bouton_ServerClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bouton.ServerClick
        Dim pass As New AutoPassword
        TextBox.Text = pass.generer(20)
End Sub

End Class

' -------------------------------------------------------------------------------------------

' Partie HTML :

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="testGenerer.aspx.vb" Inherits="archimed.testGenerer"%>
<HTML>
<HEAD>
<title>testCrypto</title>
</HEAD>

<body>
  <form id="Form1" method="post" runat="server">
        <asp:TextBox id="TextBox" runat="server" Width="20%">
        </asp:TextBox>
        <INPUT id="bouton" type="submit" value="encode" name="bouton" runat="server">
   </form>

</body>
</HTML>

Conclusion :


Voilà c'est tout simple, et en plus avec toute la panoplie de class fourni du framework.net en matière de crypto, vous avez quoi faire et varier les plaisirs :)

A noter que les risques pratiques ou théoriques de collisions (génération de mot de passe identique) sont nuls avec l'utilisation du SHA1 et supérieur. Alors les algorithme maison n'ont qu'a bien se tenir :°)

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.