Строковый вектор инициализации

Здравствуйте,пишу приложение на C# c использованием Guardant Sign, столкнулся с следующей проблемой: использую строковый(латиница) вектор инициализации для GSII64:
перед вызовом GrdApi.GrdCrypt использую:             

....
Int64 initVectorGS2 = FromStringToInt64(sInitVector);
.......
.....
byte[] bArr = new byte[8];
GrdE RetCode = GrdApi.GrdRead(keyHandle, readAdr, 8, out bArr);
RetCode = GrdApi.GrdCrypt(keyHandle,
                                   GrdAN.GSII64,
                                   bArr,
                                   (UInt32)GrdAM.OFB + (UInt32)GrdAM.Decode,        
                                   initVectorGS2);
.......

bArr - вычитываем корректно.
После декодирования получаю некорректную строку. Варианта два либо некорректно отрабатывает FromStringToInt64() либо GrdApi.GrdCrypt(), склоняюсь к некорректности FromStringToInt64().
FromStringToInt64() из примера(Test64.cs):

private static Int64 FromStringToInt64(string szInitVectorGS2)
        {
            byte[] v = new byte[(int)GrdARS.GSII64];
            //!!! object instance for unicode->ansi translation and back
            ASCIIEncoding e = new ASCIIEncoding();
            //zero previous data in array
            for (int i = 0; i < v.Length; i++)
                v[i] = 0;
            //transfer data from unicode string to byte array and prepare data for dll
            e.GetBytes(szInitVectorGS2, 0, szInitVectorGS2.Length, v, 0);
            return v[0] * 2 ^ 0 + v[1] * 2 ^ 1 + v[2] * 2 ^ 2 + v[3] * 2 ^ 3 + v[4] * 2 ^ 4 + v[5] * 2 ^ 5 + v[6] * 2 ^ 6 + v[7] * 2 ^ 7;
        }

где возможно допущена ошибка?

Re: Строковый вектор инициализации

Добрый день.
Уточните, пожалуйста, восстанавливается ли значение вектора инициализации на то же значение, какое было установлено перед шифрованием?

Выполнил у себя

byte[] bArr = new byte[8];
Int64 initVectorGS2 = FromStringToInt64("12345678");            
RetCode = GrdApi.GrdRead(GrdHandle, 0, 8, out bArr);
RetCode = GrdApi.GrdCrypt(GrdHandle,
                                GrdAN.GSII64,
                                bArr,
                                (UInt32)GrdAM.OFB + (UInt32)GrdAM.Encode,
                                initVectorGS2);

initVectorGS2 = FromStringToInt64("12345678");
RetCode = GrdApi.GrdCrypt(GrdHandle,
                                GrdAN.GSII64,
                                bArr,
                                (UInt32)GrdAM.OFB + (UInt32)GrdAM.Decode,
                                initVectorGS2);

Строка расшифровалась корректно.

Re: Строковый вектор инициализации

Алексей Перепелов пишет:

......восстанавливается ли значение вектора инициализации на то же значение.....

нет

.....Int64 initVectorGS2 = FromStringToInt64(sInitVector);....

где sInitVector=11111111
после выполнения FromStringToInt64(), initVectorGS2=12

также не ясно, следующее поведение декодировщика:

RetCode = GrdApi.GrdCrypt(keyHandle,
                               GrdAN.GSII64,
                               bArr,                
                               (UInt32)GrdAM.OFB + (UInt32)GrdAM.Decode,
                              11111111); указываю явно вектор

результирующая раскодированная строка некорректна

Re: Строковый вектор инициализации

Посмотрите в документации описание функции:

int GRD_API GrdCrypt(    
  HANDLE hGrd,
  DWORD dwAlgo,
  DWORD dwDataLng,
  void *pData,
  DWORD dwMethod,
  void *pIV,                   // <--- Ссылка на вектор
  void *pKeyBuf,
  void *pContext
);

Вектор должен передаваться ссылкой.

(2011-05-17 00:46:46 отредактировано Dmitriy)

Re: Строковый вектор инициализации

romik пишет:

Посмотрите в документации описание функции:

...................
  void *pIV,                   // <--- Ссылка на вектор
................
);

Вектор должен передаваться ссылкой.

1-это в Си подобных языках, я пишу приложение на С#(этот момент был указан в первом посте). Разработчики C# отказались от использования указателей для повышения безопасности исполнения кода, но есть возможность всеже работать с ними в unsafe блоках,но это не рекомендуеться делать.
2-в моем случае функция имеет следующий синтаксис:

public static GrdE GrdCrypt(
    Handle GrdHandle,
    GrdAN Algo,
    byte[] Data,
    uint Method,
    long pIV
)

где pIV Int64  вектор инициализации.
3-основная причиной создание топика заключаеться в примере(Samples\x64\Win64\General Guardant API\Microsoft Visual C#\Test64.cs):

// Implement data DECODING by GSII64 hardware algorithm            
            System.Console.Write("\nDecoding data by GSII64 hardware algorithm: ");
            InitVectorGS2 = FromStringToInt64("__IV___");

            RetCode = GrdApi.GrdCrypt(GrdHandle,
                                    GrdAN.GSII64,
                                    DataString,
                                    (UInt32)GrdAM.OFB + (UInt32)GrdAM.Decode,    // OFB = Output Feed Back         
                                    InitVectorGS2);                // 64-bit Init Vector

в котором используеться в качестве вектора инициализации не просто переменная типа long, а набор символов "__IV___", мой вектор также состоит из символов, но добиться корректной декодировки мне пока не удаеться, более того,вариант изменения вектора на сугубо числовое значение и передача его в явном виде, также не увенчался успехом, надеюсь на помощь разработчиков.

Re: Строковый вектор инициализации

основная причиной создание топика заключаеться в примере(Samples\x64\Win64\General Guardant API\Microsoft Visual C#\Test64.cs):

Нигде в указаном примере вектор не передаётся в явном виде, в качестве параметра функции! Он обязательно должен быть переменной, т.к. после декодирования каждого блока, функция GrdCrypt помещает в эту переменную другое значение, используемое для декодирования следующего блока. По этой причине, переменная вектора должна явно переинициализироваться одинаковым значением перед кодированием, и перед декодированием.

Re: Строковый вектор инициализации

romik пишет:

Нигде в указаном примере вектор не передаётся в явном виде, в качестве параметра функции! Он обязательно должен быть переменной

С тонкостями работы GrdCrypt не знаком, буду знать, спасибо, как все же быть с корректной декодировкой строки с символьным вектором?

Re: Строковый вектор инициализации

Объявляйте переменную, присваивайте ей символьное значение, и используйте эту переменную в качестве параметра GrdCrypt.

Re: Строковый вектор инициализации

romik пишет:

Объявляйте переменную, присваивайте ей символьное значение, и используйте эту переменную в качестве параметра GrdCrypt.

Уважаемый Михаил,просьба внимательно прочитать мой первый пост. Не думаю,что есть смысл на этом форуме писать ради того, чтобы писать, тут нет рейтингов и тому подобных статистических вещей. Этот форум -  место, где можно обменяться опытом и обсудить вопросы.

Re: Строковый вектор инициализации

Дмитрий,

значение вектора инициализации перед шифрованием и расшифрованием должно быть одним и тем же (это указано в документации) и обучающих материалах по использованию симметричных крипто алгоритмов.

Что касается функции FromStringToInt64(), то, как видно из ее кода, она выполняет некоторую свертку символьного вектора инициализации в число длиной 64 бита (по значениям ASCII-символов). Соответственно перед расшифрованием при помощи GrdCrypt() необходимо передать в FromStringToInt64() тот же верктор, что использовался при шифровании.

При необходимости можно написать собственную функцию свертки или конвертирования.

(2011-05-17 11:45:33 отредактировано Dmitriy)

Re: Строковый вектор инициализации

C FromStringToInt64() я разобрался,благодарю. Вектор инициализации перед шифрованием и расшифрованием одинаковый поэтому вопрос остается открытым, почему же не выходит расшифровать строку? До использования GrdApi.GrdCrypt, массив bArr вычитывается корректно, вектор инициализации также правильный. Некорректным результирующий массив становиться после выполнения GrdApi.GrdCrypt. Я провел сравнение: проект написанный delphi расшифровует необходимую строку на ура, при этом используеться тот же ключ и тот же ветокр инициализации, основываясь именно на делфийском проекте я и сравниваю байтовый массив до декодирования и после, повторюсь - до дектодирования оба массива корретны(как в С#, так и в Delphi), после декодирования, выполнения
С#

RetCode = GrdApi.GrdCrypt(keyHandle,GrdAN.GSII64,bArr, (UInt32)GrdAM.OFB + (UInt32)GrdAM.Decode, initVectorGS2);

Delphi

iRes:= GrdCrypt(keyHandle,GrdAN_GSII64,8,@bArr,GrdAM_OFB +  GrdAM_Decrypt,@sTmpKey[1],nil,nil);

массивы уже отличны и как следствие - в С# - расшифрованная строка - неправильная, в Delphi - строка верная.

Re: Строковый вектор инициализации

Дмитрий, а код, который я указал в своем первом комментарии работает корректно?

Если, да, то чему точно равно значение переменной initVectorGS2 и содержимое массива sTmpKey[] перед вызовом GrdCrypt при расшифровании ?

(2011-05-17 13:14:18 отредактировано Dmitriy)

Re: Строковый вектор инициализации

Алексей Перепелов пишет:

Дмитрий, а код, который я указал в своем первом комментарии работает корректно?

работает корректно

Алексей Перепелов пишет:

чему точно равно значение переменной initVectorGS2 и содержимое массива sTmpKey[] перед вызовом GrdCrypt при расшифровании ?

в Вашем примере или в моем?

Re: Строковый вектор инициализации

В Вашем примере C# и в Вашем же примере Delphi, соответственно.

Re: Строковый вектор инициализации

сам вектор инициализации равен = 11111111
C# - initVectorGS2 =12
Delphi - sTmpKey[] = 11111111

Re: Строковый вектор инициализации

Вот, собственно, и ответ. Вектор инициализации, как я уже писал, должен быть одинаковый.

То есть в Вашем случае, для корректного расшифрования необходимо, чтобы initVectorGS2 был равен 0x3131313131313131 (восемь единиц в ASCII). Как я уже писал, FromStringToInt64() не занимается конвертированием, а делает свертку (получается число 12).

Чтобы FromStringToInt64 именно конвертировала, ее код необходимо изменить, чтобы она возвращала

return v[0] * ((Int64)1 << 0) + v[1] * ((Int64)1 << 8) + v[2] * ((Int64)1 << 16) + v[3] * ((Int64)1 << 24) + v[4] * ((Int64)1 << 32) + v[5] * ((Int64)1 << 40) + v[6] * ((Int64)1 << 48) + v[7] * ((Int64)1 << 56);

Re: Строковый вектор инициализации

Работает?

Думаю, так пример будет немного понятнее, поэтому мы поменяем его с выходом следующего релиза.

(2011-05-17 13:58:14 отредактировано Dmitriy)

Re: Строковый вектор инициализации

        private static Int64 FromStringToInt64(string szInitVectorGS2)
        {
            byte[] v = new byte[(int)GrdARS.GSII64];
            ASCIIEncoding e = new ASCIIEncoding();
            for (int i = 0; i < v.Length; i++)
                v[i] = 0;
            e.GetBytes(szInitVectorGS2, 0, szInitVectorGS2.Length, v, 0);

//-        v    {byte[8]}    byte[]
//        [0]    49    byte
//        [1]    49    byte
//        [2]    49    byte
//        [3]    49    byte
//        [4]    49    byte
//        [5]    49    byte
//        [6]    49    byte
//        [7]    49    byte

            Int64 result = v[0] * ((Int64)1 << 0) + v[1] * ((Int64)1 << 8) + v[2] * ((Int64)1 << 16) + v[3] * ((Int64)1 << 24) + v[4] * ((Int64)1 << 32) + v[5] * ((Int64)1 << 40) + v[6] * ((Int64)1 << 48) + v[7] * ((Int64)1 << 56);
return result;
        }

result = 3544668469065756977 = 0x3131313131313131, но строка так и не раскодировалась нормально....

Или я Вас не правильно понял или где-то что-то упущено.

Re: Строковый вектор инициализации

В смысле FromStringToInt64() поняли все правильно.

Так как расшифрование само по себе работает корректно, значит дело в параметрах.

Остается сравнить остальные параметры аналогичным образом и понять, где отличие.

(2011-05-17 15:14:18 отредактировано Dmitriy)

Re: Строковый вектор инициализации

Алексей Перепелов пишет:

Остается сравнить остальные параметры аналогичным образом и понять, где отличие.

Не выходит каменный цветок....

        private string GetParameter(Guardant.Handle keyHandle, string sInitVector, GrdSAM readAdr)
        {

            string result = "";
            byte[] bArr = new byte[8];
            GrdE RetCode = GrdApi.GrdRead(keyHandle, readAdr, 8, out bArr);
            ErrorHandling(keyHandle, RetCode);
            Int64 initVectorGS2 = FromStringToInt64(sInitVector); 
            RetCode = GrdApi.GrdCrypt(keyHandle,
                                            GrdAN.GSII64,
                                            bArr, //C#=Delphi={246,58,75,196,231,189,225,186} (зашифровано слово test)
                                            (UInt32)GrdAM.OFB + (UInt32)GrdAM.Decode,
                                            initVectorGS2); // =3544668469065756977

            ErrorHandling(keyHandle, RetCode);
            result = BArrToStr(bArr); //в С#= {20,227,46,96,2,193,246,122}, Delphi={116,101,115,116,0,0,0,0}
            return result;
        }

все-таки думаю, что не правильно FromStringToInt64() конвертирует вектор

Re: Строковый вектор инициализации

Странно. Уточните, пожалуйста, версию Guardant API (версию комплекта разработчика), а также определитель и флаги дескриптора используемого алгоритма (под номером 0). Попробую расшифровать "test" у себя.

Re: Строковый вектор инициализации

Алексей Перепелов пишет:

Уточните, пожалуйста, версию Guardant API (версию комплекта разработчика).....

Версия комплекта: 5.51 от 13.12.2010

Алексей Перепелов пишет:

.....определитель и флаги дескриптора.....

GSII64,
0000 DD 24 65 0E A3 0A 96 5D 
0008 E5 CD 7E 17 7D 94 B4 E7
0010

P.S.Хочу поблагодарить Вас, Алексей,  за помощь, не каждая тех.поддержка после стольких ответов, будет продолжать искать решение, спасибо.

Re: Строковый вектор инициализации

Dmitriy пишет:
romik пишет:

Объявляйте переменную, присваивайте ей символьное значение, и используйте эту переменную в качестве параметра GrdCrypt.

Уважаемый Михаил,просьба внимательно прочитать мой первый пост. Не думаю,что есть смысл на этом форуме писать ради того, чтобы писать, тут нет рейтингов и тому подобных статистических вещей. Этот форум -  место, где можно обменяться опытом и обсудить вопросы.

Извините что пытался помочь, отвечая на заданый мне вопрос "как все же быть с корректной декодировкой строки с символьным вектором?". Больше не буду.

Re: Строковый вектор инициализации

Дмитрий,

Предполагаю, что Вы используете Embarcadero RAD Studio 2010 (или что-то подобное).

Если так, то судя по всему, проблема в компиляторе  (или настройках компилятора/отладчика).

Пробовал зашифровать "test" в C++, C# и Delphi 7 - получил 150 188 22 208 229 124 23 192
Тот же код шифрования "test" в RAD Studio 2010 выдает 246 58 75 196 231 189 225 186

Вряд ли я ошибся в коде, так как, в частности, в Rad-студии и Delphi 7 компилировался один и тот же исходник. Результаты разные.

Я как-то встречался уже раньше с подобным "своеволием" приложения, собранного в Rad-студии. Однако тогда не было времени разбираться. В результате пришлось компилировать все в Delphi 7.

Попробуйте Delphi 7. Если заработает - хорошо. И если вдруг поймете, что нужно Rad-студии для нормальной работы - буду рад, если поделитесь.

(2011-05-17 19:06:23 отредактировано Dmitriy)

Re: Строковый вектор инициализации

Не ясная ситуация конечно, можно ли как-то поставить эту проблему на повестку дня, официально получить ответ от Guardant, как можно решит данный вопрос.
P.S.Более детально о нашем проекте я написал Вам в письме и отправил на hotline@guardant.ru с темой "для Алексея Перепелова"