BYTE.PARSE (C #): форматетеэксекция на шестнадцатеричной строке

StackOverflow https://stackoverflow.com//questions/25001693

Вопрос

На самом деле я пытаюсь реализовать очень простой меканизм входа в систему для приложения, который я разработан в Visual C # .NET 2.0 на встроенном устройстве. После некоторых исследований я нашел на MSDN A образца кода выполнения перемешивания пароля:

Как хранить пароли < / P >.

К сожалению, когда я пытаюсь использовать его, что образец кода поднимает форматэксемент на вызов для byte.Parse на подсусах шестнадцатеричной строки RenacodicCode. У меня действительно проблемы, чтобы понять, почему, так как я не сделал никаких изменений в код.

Вот код:

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
//...
}
}
.

Я только изменил одну строку:

SaltValue

к

string saltValueString = utf16.GetString(saltValue);

Потому что первая версия метода, похоже, не доступна для встроенного C #. Но в любом случае, я тестировал без изменения этой линии (на не встроенной среде), и она все еще поднимала форматексертизацию.

Я скопировал значение string saltValueString = utf16.GetString(saltValue, 0, SaltValueSize); от этого образец другого кода MSDN (который связан): Как проверить пароли

Тест, который поднимает исключение:

SaltValueSize

Это было полезно?

Решение

Проблема заключается в том, что ваш метод GenerateSaltValue не возвращает строку гексадимических чисел.

Это возвращает строку каких-либо случайных символов, которые могут быть или обычно могут быть недействительными шестнадцатеричными символами - для меня она создала строку в основном китайских иероглифов, которые наверняка не паляются с помощью Byte.parse Метод.

также, ваш пример относится к Microsoft Commerce Server - I не имею, что это так.

"РЕШЕНИЕ:"

Я не уверен, что все эти примеры хотят выполнить с помощью этих строковых тобексов, но для этого, чтобы успешно выполнить генераторыSTValue, должно быть что-то вроде:

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;
}
.

И ваша программа будет "работать", благодаря Как вы преобразуете массив байтов в шестнадцатеричную строку и наоборот?

Но:

    .
  • Использование случайных для создания соли - плохое представление.
  • string-tohex-tobinary преобразование выглядит даже ухудшению.
  • и другие проблемы ...

так:

Прочитайте некоторые статьи, которые действительно относятся к хешированию пароля C #, как:

Hash и солевые пароли в C #

и будьте очень внимательны при поиске примеров кода - они могут использовать другую версию, платформу или даже язык. Удачи.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top