giovedì 18 novembre 2010

Confronto con password criptate in Aspnet_Membership

Ultimamente mi sono trovato ad affrontare un problema singolare, ovvero la necessità di confrontare una password inserita da un utente su un programma client Windows Form con una password memorizzata e gestita da Asp.net, nella tabella Aspnet_Membership.

Il problema principale è che la password di Asp.net è salvata criptata e non possibile decrittarla. L'unica cosa da fare, quindi, è quella di crittare allo stesso modo la password che abbiamo in chiaro e confrontare i due valori criptati. Per fare questo è necessario però il "Salt", ovvero il valore che Asp.net si salva nella colonna PasswordSalt sempre su Aspnet_Membership.

Ecco a voi la procedura (mi scuso ma non ho avuto tempo di sistemare i colori :D ):

VB.Net


Public Function Confronta(ByVal password As String, ByVal aspnetSalt As String, ByVal aspnetPassword As String) As Boolean
    Dim isEqual As Boolean = False
    If aspnetPassword = GenerateHash(password, aspnetSalt) Then
        isEqual = True
    End If
    Return isEqual
End Function

Private Function GenerateHash(ByVal pwd As String, ByVal salt As String) As String
    Dim p1 As Byte() = Convert.FromBase64String(salt)
    Return GenerateHash(pwd, p1)
End Function

Private Function GenerateHash(ByVal pwd As String, ByVal saltAsByteArray As Byte()) As String
    Dim sha As New System.Security.Cryptography.SHA1CryptoServiceProvider()
    Dim p1 As Byte() = saltAsByteArray
    Dim p2 As Byte() = System.Text.Encoding.Unicode.GetBytes(pwd)
    Dim data() As Byte = New Byte(((p1.Length + p2.Length)) - 1) {}
    p1.CopyTo(data, 0)
    p2.CopyTo(data, p1.Length)
    Dim result As Byte() = sha.ComputeHash(data)
    Dim rtn As String = Convert.ToBase64String(result)
    Return rtn
End Function


C#

public boolean Confronta(string password, string aspnetSalt, string aspnetPassword)
{
    boolean isEqual = False
    If (aspnetPassword = GenerateHash(password, aspnetSalt))
    {
        isEqual = True
    }
    return isEqual
}

private string GenerateHash(string pwd, string saltAsBase64)
{
    byte[] p1 = Convert.FromBase64String(saltAsBase64);
    return GenerateHash(pwd, p1);
}

private string GenerateHash(string pwd, byte[] saltAsByteArray)
{
    System.Security.Cryptography.SHA1 sha = new System.Security.Cryptography.SHA1CryptoServiceProvider();

    byte[] p1 = saltAsByteArray;
    byte[] p2 = System.Text.Encoding.Unicode.GetBytes(pwd);

    byte[] data = new byte[p1.Length + p2.Length];

    p1.CopyTo(data, 0);
    p2.CopyTo(data, p1.Length);

    byte[] result = sha.ComputeHash(data);

    string res = Convert.ToBase64String(result);
    return res;
}

venerdì 12 novembre 2010

Prima lettera maiuscola (Capitalize) in Sql Server

C'è un modo molto semplice per fare, in Sql Server (con T-SQL) quello che in inglese si chiama "Capitalize", ovvero rendere una stringa con la prima lettera maiuscola e tutto il resto in minuscolo.

Se la necessità è solo in output, basta usare la seguente SELECT:

SELECT UPPER(LEFT(Colonna,1)) + LOWER(SUBSTRING(Colonna,2,LEN(Colonna))) FROM Tabella


Se, invece, la necessità è quella di modificare i da dati nel database:

UPDATE Tabella SET Colonna=UPPER(LEFT(Colonna,1)) + LOWER(SUBSTRING(Colonna,2,LEN(Colonna)))