Pergunta

Na verdade, estou tentando implementar uma forma muito simples de login mecanismo para um aplicativo que eu estou desenvolvendo em Visual C# .NET 2.0 em um dispositivo embarcado.Depois de algumas pesquisas, encontrei na msdn um exemplo de código a realização de hash de senha :

Como armazenar senhas

Infelizmente, quando eu tento usá-lo, que o código de exemplo está levantando um FormatException na chamada para byte.Parse no subcadeias de caracteres da seqüência de caracteres hexadecimal SaltValue.Eu realmente tenho dificuldade de entender por que, desde que eu não tenha feito qualquer alteração no código.

Aqui está o código :

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.Globalization;

private const int SaltValueSize = 4;

private static string GenerateSaltValue()
{
UnicodeEncoding utf16 = new UnicodeEncoding();

if (utf16 != null)
{
    // Create a random number object seeded from the value
    // of the last random seed value. This is done
    // interlocked because it is a static value and we want
    // it to roll forward safely.

    Random random = new Random(unchecked((int)DateTime.Now.Ticks));

    if (random != null)
    {
        // Create an array of random values.

        byte[] saltValue = new byte[SaltValueSize];

        random.NextBytes(saltValue);

        // Convert the salt value to a string. Note that the resulting string
        // will still be an array of binary values and not a printable string. 
        // Also it does not convert each byte to a double byte.


        //Original line :
        //string saltValueString = utf16.GetString(saltValue);
        //Replaced by :
        string saltValueString = utf16.GetString(saltValue, 0, SaltValueSize);

        // Return the salt value as a string.

        return saltValueString;
    }
}

return null;
}

private static string HashPassword(string clearData, string saltValue, HashAlgorithm hash)
{
UnicodeEncoding encoding = new UnicodeEncoding();

if (clearData != null && hash != null && encoding != null)
{
    // If the salt string is null or the length is invalid then
    // create a new valid salt value.

    if (saltValue == null)
    {
        // Generate a salt string.
        saltValue = GenerateSaltValue();
    }

    // Convert the salt string and the password string to a single
    // array of bytes. Note that the password string is Unicode and
    // therefore may or may not have a zero in every other byte.

    byte[] binarySaltValue = new byte[SaltValueSize];

    //FormatException raised here
    binarySaltValue[0] = byte.Parse(saltValue.Substring(0, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
    binarySaltValue[1] = byte.Parse(saltValue.Substring(2, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
    binarySaltValue[2] = byte.Parse(saltValue.Substring(4, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);
    binarySaltValue[3] = byte.Parse(saltValue.Substring(6, 2), System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture.NumberFormat);

//...
//Some more code
//...
}
}

Eu só alterou uma linha :

string saltValueString = utf16.GetString(saltValue);

para

string saltValueString = utf16.GetString(saltValue, 0, SaltValueSize);

porque a primeira versão de o método não parecem estar disponíveis para o embedded C#.Mas de qualquer maneira eu testei sem alterar esta linha (não incorporado ambiente), e ele ainda estava criando um FormatException.

Que eu tenha copiado o SaltValueSize valor a partir de outros msdn exemplo de código (que está relacionado com) :Como validar senhas

O teste que aumenta a exceção :

HashPassword("youpi", null, new SHA1CryptoServiceProvider());

Foi útil?

Solução

O problema reside no fato de que seu GenerateSaltValue o método não retornar cadeia de hexademical números.

Ele retorna a seqüência de alguns símbolos aleatórios, que podem ou normalmente não pode ser válida hexademical símbolos - para mim é criado cadeia de maioria Chinesa hieróglifos que com certeza não são analisáveis por Byte.Analisar o método.

Também, o exemplo que se refere ao Microsoft Commerce Server - Eu não tenho nenhuma idéia de tudo o que ele é.

"SOLUÇÃO:"

Eu não estou certo de que todos estes exemplos deseja atingir com esta cadeia-tohex-tobinary conversões, mas para executar com êxito o GenerateSaltValue deve ser algo como:

public static string ByteArrayToString(byte[] byteArray)
{
    StringBuilder hex = new StringBuilder(byteArray.Length * 2);

    foreach (byte b in byteArray)
        hex.AppendFormat("{0:x2}", b);

    return hex.ToString();
}

// Renamed GenerateSaltValue method
private static string GenerateHexSaltString()
{
    Random random = new Random();

    // Create an array of random values.
    byte[] saltValue = new byte[SaltValueSize];

    random.NextBytes(saltValue);

    string saltValueString = ByteArrayToString(saltValue);

    // Return the salt value as a string.
    return saltValueString;
}

E o seu programa de "trabalho", graças a Como converter de Byte Matriz de Seqüência de caracteres Hexadecimal e vice-versa?

MAS:

  • Usando Random para Sal a criação é uma má idéia.
  • cadeia-tohex-tobinary conversão parece mesmo worser.
  • E outros problemas...

ASSIM:

Leia alguns artigos que realmente pertence a C# hash de senha e criptografia, como:

Hash do sal e senhas em C#

E estar muito atento enquanto estiver procurando por exemplos de código - eles poderiam usar outra versão, plataforma ou até mesmo a linguagem.Boa sorte.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top