Wygląda na to, że istnieje 6 odmian algorytmu CBC-MAC. Próbowałem dopasować algorytm MAC do PINPad 1000SE [który zgodnie z instrukcją jest algorytmem ISO 9797-1 1].ISO 9797-1 Algorytm 1 [CBC-MAC] w C#
Mam doskonały początek od here.
I kodowane algorytmem, jak poniżej:
public static byte[] CalculateMAC(this IPinPad pinpad, byte[] message, byte[] key)
{
//Divide the key with Key1[ first 64 bits] and key2 [last 64 bits]
var key1 = new byte[8];
Array.Copy(key, 0, key1, 0, 8);
var key2 = new byte[8];
Array.Copy(key, 8, key2, 0, 8); //64 bits
//divide the message into 8 bytes blocks
//pad the last block with "80" and "00","00","00" until it reaches 8 bytes
//if the message already can be divided by 8, then add
//another block "80 00 00 00 00 00 00 00"
Action<byte[], int> prepArray = (bArr, offset) =>
{
bArr[offset] = 0; //80
for (var i = offset + 1; i < bArr.Length; i++)
bArr[i] = 0;
};
var length = message.Length;
var mod = length > 8? length % 8: length - 8;
var newLength = length + ((mod < 0) ? -mod : (mod > 0) ? 8 - mod : 0);
//var newLength = length + ((mod < 0) ? -mod : (mod > 0) ? 8 - mod : 8);
Debug.Assert(newLength % 8 == 0);
var arr = new byte[newLength];
Array.Copy(message, 0, arr, 0, length);
//Encoding.ASCII.GetBytes(message, 0, length, arr, 0);
prepArray(arr, length);
//use initial vector {0,0,0,0,0,0,0,0}
var vector = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
//encrypt by DES CBC algorith with the first key KEY 1
var des = new DESCryptoServiceProvider { Mode = CipherMode.CBC };
var cryptor = des.CreateEncryptor(key1, vector);
var outputBuffer = new byte[arr.Length];
cryptor.TransformBlock(arr, 0, arr.Length, outputBuffer, 0);
//Decrypt the result by DES ECB with the second key KEY2 [Original suggestion]
//Now I'm Encrypting
var decOutputBuffer = new byte[outputBuffer.Length];
des.Mode = CipherMode.ECB;
var decryptor = des.CreateEncryptor(key2, vector);
//var decryptor = des.CreateDecryptor(key2, vector);
decryptor.TransformBlock(outputBuffer, 0, outputBuffer.Length, decOutputBuffer, 0);
//Encrypt the result by DES ECB with the first key KEY1
var finalOutputBuffer = new byte[decOutputBuffer.Length];
var cryptor2 = des.CreateEncryptor(key1, vector);
cryptor2.TransformBlock(decOutputBuffer, 0, decOutputBuffer.Length, finalOutputBuffer, 0);
//take the first 4 bytes as the MAC
var rval = new byte[4];
Array.Copy(finalOutputBuffer, 0, rval, 0, 4);
return rval;
}
Wtedy odkryłem tam są 3 programy padding i ten, który dał mi start może niekoniecznie mieć rację. Podręcznik ponownie przyszedł mi na ratunek. Wygląda na to, że urządzenie zawiera tylko pady z 0s. Dodatkowy blok jest również nigdzie nie wspomniano więc zrobiłem poniższe zmiany:
Action<byte[], int> prepArray = (bArr, offset) =>
{
bArr[offset] = 0; ... }
Brak dodatkowych bloku (jeśli mod 0 [podzielna przez 8] nie zmieniają długości array)
var newLength = length + ((mod < 0) ? -mod : (mod > 0) ? 8 - mod : 0);
Pierwotna propozycja chciał mnie do odszyfrowania w drugim kroku ... ale Valery here sugeruje, że jest zaszyfrowany do końca. Więc zmieniłem Decrypt na Encrypt. Ale wciąż nie jestem w stanie uzyskać wymaganego adresu MAC ...
Instrukcja mówi o kluczu "6AC292FAA1315B4D8234B3A3D7D5933A" [ponieważ klucz powinien mieć 16 bajtów, domyśliłem się, że klucz jest tutaj ciągiem szesnastkowym, więc wziąłem bajt wartości 6A, C2 , 92, FA ... nowy bajt [] {106, 194, 146, ...] MAC powinien być 7B, 40, BA, 95 [4 bajty], jeśli wiadomość jest [0x1a + tablica bajtów MENTERODOMETER]
Czy ktoś może pomóc? Proszę?
Od pinpad wymaga, że pierwszy znak w wiadomości jest 0x1a ...
public static byte[] CalculateAugmentedMAC(this IPinPad pinpad, string message, byte[] key)
{
var arr = new byte[message.Length + 1];
var source = Encoding.ASCII.GetBytes(message);
arr[0] = 0x1a; //ClearScreenIndicator
Array.Copy(source, 0, arr, 1, source.Length);
return CalculateMAC(pinpad, arr, key);
}
Dzwonię powyższy kod z tego wejścia:
var result = pad.CalculateAugmentedMAC("MENTERODOMETER", new byte[] { 106, 194, 146, 250, 161, 49, 91, 77, 130, 52, 179, 163, 215, 213, 147, 58 });
Ciekawy. Dlaczego warto angażować się w en/deszyfrowanie danych PINPad? Przepływ pracy PINPad przeznaczony jest do wysyłania zaszyfrowanych danych bezpośrednio do banku handlowca za pomocą kluczy DUKPT wygenerowanych przez bank i zainstalowanych w PINPadzie przez dostawcę PINPad. Nawet dotarliśmy do punktu, w którym pisaliśmy oprogramowanie do bezpośredniego kontrolowania różnych interfejsów PINPAD i innych zachowań, nigdy nie byliśmy w stanie, ani nie musieliśmy szyfrować/odszyfrowywać zaszyfrowanej koperty danych PIN dostarczonej w ramach procesu. – Bill
Bill, masz rację ... Ale jeśli masz napisać aplikację do zarządzania lojalnością, która pozwala patronom na kod PIN, musisz go użyć bez tych wcześniej zaprogramowanych kluczy .... Wcześniejszy model PINPad 1000SE - nie pamiętam na wierzch mojej głowy - pozwoliło ci uzyskać kod PIN i wysłać go jako czysty tekst. Późniejsze modele szyfrują kod PIN i nie możemy się do niego dostać ... –