C# : шифрование ПИН-блока в ISO8583

Рейтинг: 1Ответов: 2Опубликовано: 15.04.2015

Добрый день.

Сейчас пишу реализацию протокола ISO8553, а конкретнее - установка / смена PIN'а карты. Поле 52 - зашифрованный ПИН-блок, где на основании ПИНа формируется ПИН-блок, затем он шифруется.

Для полноты картину приведу описание этого поля из стандарта:

ENCRYPTED PIN BLOCK. For more comfortable viewing hence and further PERSONAL IDENTIFICATION DATA is presented as 16 HEXADECIMAL characters 0-9, A-F in the ASCII with separator ‘.’ between each two characters

Пример заполненного поля:

34.56.F4.3B.6E.D2.77.8B

Теперь вопрос:

В описании написано, что пин-блок (а это 16(!) символов переводится в HEX, с разделителем точкой) Приведенный мною выше пример заполнения поля в HEX-эдиторе не расшифровывается вообще.

Пример моего ПИН-блока: (тут ПИН = 1234, формат 1)

1412345478541264

Так я перевожу строку ПИН-блока в HEX:

 foreach (char t in PIN_block_encr)
                sb.Append(Convert.ToInt32(t).ToString("x") + ".");

Мне кажется, я где-то ошибаюсь или чего-то недопонимаю :(

Как правильно перевести в моем случае 16 символов ПИН-блока (тип string) в HEX?

Спасибо.

Ответы

▲ 2Принят

Смотря что вам надо получить.

Если вы хотите перевести побайтно, и вывести все байты разделив их точкой, то вам для начала нужно разделить число на байты. Как это делать, зависит от точного типа. Например, может подойти

var bytes = BitConverter.GetBytes(number);

(Заметьте, что number должен быть числом, а не строкой. Если это строка, надо предварительно перевести его в число подходящего типа.)

Затем можно закодировать каждый байт:

string.Join(".", bytes.Select(b => b.ToString("X"));

Если вам нужно перевести всё число в «большую» шестнадцатеричную строку, делайте как написано здесь.


Если вам, наоборот, надо считать число из вашей записи, делаем так:

Разбиваем строку на части:

var parts = s.Split('.');

Каждую часть раскодируем:

var bytes = parts.Select(p => byte.Parse(p, NumberStyles.HexNumber));

И склеиваем в число. Поскольку у вас 8 байт, подойдёт ulong:

var result = BitConverter.ToUInt64(bytes.ToArray(), 0);
▲ 1

Написано же: ENCRYPTED PIN BLOCK. Как вы вообще хотели посмотреть его в шестнадцатиричном редакторе без предварительной расшифровки?