Удалённое обновление ключа.

Добрый день!
Есть у нас Guardant Sign ключи. Для удобства, обновление некоторых данных, мы решили реализовать Удалённое обновление. Но при попытке выполнить метод GrdTRU_DecryptQuestion, получаем ошибку GrdE_InvalidData. Для проверки мы после выполнения GrdTRU_GenerateQuestion, сразу передаем результаты в GrdTRU_DecryptQuestion.

А вот сам код

 var guardantHandle = new Handle();

            try
            {
                var retCode = GrdApi.GrdStartup(GrdFMR.Local); // инициализация Guardant API для локального ключа

                if (retCode == GrdE.OK)
                {
                    guardantHandle = GrdApi.GrdCreateHandle(guardantHandle, GrdCHM.MultiThread); // создаем защищеный контейнер

                    retCode = GrdApi.GrdSetAccessCodes(guardantHandle, PublikKey + CryptyKey, PrivatrRead + CryptyKey); // помещает коды доступа к ключу в защищенный контейнер. Эти коды будут использоваться при выполнении операций с ключом, для которых необходимы соответствующие коды. Коды доступа к ключу в защищенном контейнере хранятся в зашифрованном виде. Guardant API контролирует целостность кодов доступа.

                    if (retCode == GrdE.OK)
                    {
                        retCode = GrdApi.GrdLogin(guardantHandle, 0, GrdLM.Read); // авторизации и регистрация контейнира в ключе

                        if (retCode == GrdE.OK)
                        {
                            if (guardantHandle.Address != 0)
                            {
                                if (retCode == GrdE.OK)
                                {
                                    byte[] question; // буфер, куда будет помещен сгенерированный вопрос.
                                    byte[] hash; // буфер, куда будет помещено значение MAC (Message Authentication Code - кода аутентификации сообщения) для верификации вопроса.
                                    uint publicKey; // буфер, куда будет помещено численное значение Public code ключа, для которого сгенерирован вопрос.
                                    uint id;

                                    retCode = GrdApi.GrdTRU_GenerateQuestion(guardantHandle, out question, out id, out publicKey, out hash);

                                    if (retCode == GrdE.OK)
                                    {
                                        if (retCode == GrdE.OK)
                                        {
                                            var ms = new MemoryStream();

                                            var bw = new BinaryWriter(ms);

                                            bw.Write(question, 0, question.Length);
                                            bw.Write(id);
                                            bw.Write(publicKey);
                                            bw.Write(hash, 0, hash.Length);

                                            ms.Seek(0, SeekOrigin.Begin);

                                            retCode = GrdApi.GrdTRU_DecryptQuestion(
                                                guardantHandle,
                                                (uint)GrdAN.GSII64,
                                                (uint)GrdAN.HASH64,
                                                question,
                                                id,
                                                publicKey,
                                                hash);
                                            //return ms;
                                        }
                                        else
                                        {
                                            throw new Exception(HardwareKeyErrrorMenager.GetErrorText(retCode));
                                        }
                                    }
                                }
                                else
                                {
                                    throw new Exception(LocalizationManager.GetLocalisationTex("CANT_GET_HARDWAREKEY_ID"));
                                }
                            }
                            else
                            {
                                throw new Exception(LocalizationManager.GetLocalisationTex("ADDRESS_NOT_FOUNDER"));
                            }
                        }
                        else
                        {
                            throw new Exception(HardwareKeyErrrorMenager.GetErrorText(retCode));
                        }
                    }
                    else
                    {
                        throw new Exception(HardwareKeyErrrorMenager.GetErrorText(retCode));
                    }
                }
                else
                {
                    throw new Exception(HardwareKeyErrrorMenager.GetErrorText(retCode));
                }
            }
            finally
            {
                GrdApi.GrdLogout(guardantHandle);
                GrdApi.GrdCloseHandle(guardantHandle);
                GrdApi.GrdCleanup();
            }

Re: Удалённое обновление ключа.

И еще такой вопрос. Почему при выполенния генерации вопроса, переменная hash возвращаться 16 байтами, а не 8? При том что 8 байт пустышки (0)!

Re: Удалённое обновление ключа.

Подтвердите, что по адресам ячеек GrdAN.GSII64 и GrdAN.HASH64 действительно находятся указанные алгоритмы, и в качестве дескриптора указан ключ шифрования TRU из обновляемого ключа?

Насчет 16 байт прокомментировать не могу, но по документации использовать надо именно 8 для Sign-ключей. Наша .net-библиотека никак не переопределяет типы данных и возвращаемый размер - работа идет через стандартных механизм PlatformInvoker. Передал запрос разработчику.

Re: Удалённое обновление ключа.

Добрый день!
С ключами разобрались. ключи были инициализированы напрямую через сишную библиотеку. Обновление проходить удачно но данные не записываться. Есть подозрение это из-за того что GrdTRU_EncryptAnswer генерирует лишние байты, а именно 10 тыс. Хотя выделялось 152, а возвращает 10152.

Re: Удалённое обновление ключа.

Добрый день.

grifin85 пишет:

Добрый день!
С ключами разобрались. ключи были инициализированы напрямую через сишную библиотеку. Обновление проходить удачно но данные не записываться. Есть подозрение это из-за того что GrdTRU_EncryptAnswer генерирует лишние байты, а именно 10 тыс. Хотя выделялось 152, а возвращает 10152.

Нет, размер возвращаемых данных функцией GrdTRU_EncryptAnswer тут не важен.

Пример рабочего TRU-приложения:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Guardant;

namespace Guardant.grdTRUSample
{
  class Program
  {
    static int Main(string[] args)
    {
      #region Variables definition
      // ------------------------------------------------
      // Variables definition
      // ------------------------------------------------

      GrdE RetCode;                       // Error code for all Guardant API functions

      Handle GrdHandle = new Handle();    // Creates empty handle for Guardant protected container
      // NOTE: Use IntPtr type instead of Handle if you want to use old-style functions and unsafe context; 
      // If you need to convert from Handle to IntPtr use this hint: new IntPtr(Handle.Address)

      // Data variables 
      uint CryptPU = 0x8566783U;         // Random value for access codes security                              
      uint CryptRD = 0x17d49c84U;        // Random value for access codes security                              
      uint CryptWR = 0x9843de24U;        // Random value for access codes security                              
      uint CryptMS = 0x47832845U;        // Random value for access codes security                              

      // Demo codes decreased by random value for better security;
      // This way they are not shown in the application
      uint PublicCode = (uint)GrdDC.DEMONVK - CryptPU;    // Must be encoded             
      uint ReadCode = (uint)GrdDC.DEMORDO - CryptRD;    // Must be encoded             
      uint WriteCode = (uint)GrdDC.DEMOPRF - CryptWR;    // Must be encoded             
      uint MasterCode = (uint)GrdDC.DEMOMST - CryptMS;    // Must be encoded   

      // Variables to use in GrdSetFindMode()
      GrdFMR RemoteMode;         // Operation mode flags                    
      GrdFM DongleFlags;        // Operation mode flags                    
      uint ProgramNumber = 0;  // Program number                          
      uint Version = 0;        // Version                                 
      uint DongleID = 0;       // Dongle ID
      uint ModelID = 0;        // Dongle model
      byte[] TypeID = new byte[2];// Dogle type
      uint SerialNumber;       // Serial number                           
      uint BitMask;            // Bit mask                                
      GrdDT DongleType;         // Dongle type                             
      GrdFMM DongleModel;        // Dongle model                             
      GrdFMI DongleInterface;    // Dongle interface                             

      FindInfo FindInfo = new FindInfo();   // structure used in GrdFind()

      // for GrdWrite() and GrdRead()
      UInt32 TempData;           // Temporary data         
      Byte[] PIData = new Byte[(Int32)GrdADS.GSII64_DEMO];

      uint CRC_Before;            // CRC of original data                    
      uint CRC_After;             // CRC of restored data                    
      byte[] DigestBefore = new byte[(int)GrdSHA256.DIGEST_SIZE];    // SHA256 of original data                    
      byte[] DigestAfter = new byte[(int)GrdSHA256.DIGEST_SIZE];    // SHA256 CRC of restored data

      // Object instance for unicode -> ansi translation and back
      ASCIIEncoding AsciiEncoder = new ASCIIEncoding();

      byte[] GrdSHA256_Context = new byte[(int)GrdSHA256.CONTEXT_SIZE];
      byte[] GrdAES_Context = new byte[(int)GrdAES.CONTEXT_SIZE];

      //Int32 LMS;
      uint LMS; // VS2012

      byte[] PublicKey = { 0x1D, 0xCE, 0x42, 0x91, 0xEF, 0xF6, 0x8C, 0x6A, 0xEC, 0xB6, 0xC6, 0x76, 0x7E, 0xF0, 0xCC, 0x0B, 0x61, 0xD5, 0xA1, 0x73, 0x69, 0x14, 0x53, 0x05, 0xC3, 0xFD, 0x98, 0x93, 0xD6, 0x0A, 0xF8, 0xFA, 0x03, 0xE1, 0x8C, 0x37, 0x99, 0x4B, 0x95, 0x6B }; //"\x1D\xCE\x42\x91\xEF\xF6\x8C\x6A\xEC\xB6\xC6\x76\x7E\xF0\xCC\x0B\x61\xD5\xA1\x73\x69\x14\x53\x05\xC3\xFD\x98\x93\xD6\x0A\xF8\xFA\x03\xE1\x8C\x37\x99\x4B\x95\x6B";
      byte[] DataForSign = new byte[20];                            // Test data for ECC160 algo
      byte[] SignResult = new byte[40];                            // Sign result of ECC160 algo
      GrdSystemTime GrdSystemTime = new GrdSystemTime();

      string TestDataString = "___ Test Data string for Encode/Decode. Length of 64 bytes ____";
      Int64 InitVectorGS2 = 12345678;                                // Init. Vector for GSII64 algo 
      byte[] InitVectorAES = new byte[(int)GrdAES256.BLOCK_SIZE];    // Init. Vector for AES256 algo 
      string szInitVectorAES = "";
      string szDataPsw = "__Password for encrypt/decrypt__";
      byte[] DataPassword = new byte[32];
      byte[] DataString = new byte[64];

      // Converting from unicode string szDataStr to byte array abyDataStr
      AsciiEncoder.GetBytes(TestDataString, 0, TestDataString.Length, DataString, 0);

      // Converting from unicode string szDataPsw to byte array abyDataPsw
      AsciiEncoder.GetBytes(szDataPsw, 0, szDataPsw.Length, DataPassword, 0);

      byte[] abyDataInitVector = new byte[32];



      byte[] g_byDongleImage = {0x28, 0x02, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
0xCA, 0x04, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 
0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 
0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, 0x00, 
0x76, 0x00, 0xD2, 0x00, 0x2E, 0x01, 0x8A, 0x01, 
0xEA, 0x01, 0x46, 0x02, 0xA2, 0x02, 0xFE, 0x02, 
0x5A, 0x03, 0xB6, 0x03, 0x02, 0x04, 0x6E, 0x04, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x08, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x0A, 0x00, 0x00, 0x00, 0x49, 0x54, 0x66, 0x89, 
0x84, 0x69, 0x83, 0x83, 0x84, 0x68, 0x83, 0x89, 
0x80, 0x72, 0x69, 0x82, 0x08, 0x06, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 
0x49, 0x54, 0x66, 0x89, 0x84, 0x69, 0x83, 0x83, 
0x84, 0x68, 0x83, 0x89, 0x80, 0x72, 0x69, 0x82, 
0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x0A, 0x00, 0x00, 0x00, 0x49, 0x54, 0x66, 0x89, 
0x84, 0x69, 0x83, 0x83, 0x84, 0x68, 0x83, 0x89, 
0x80, 0x72, 0x69, 0x82, 0x08, 0x0C, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 
0xA2, 0x2F, 0x4C, 0x68, 0x8A, 0xD8, 0xD9, 0xD1, 
0x6D, 0x3E, 0x9A, 0xFB, 0xA7, 0x7D, 0x5F, 0x5B, 
0x66, 0xF5, 0xB2, 0xF8, 0x08, 0x0D, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 
0x49, 0x54, 0x66, 0x89, 0x84, 0x69, 0x83, 0x83, 
0x84, 0x68, 0x83, 0x89, 0x80, 0x72, 0x69, 0x82, 
0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x0A, 0x00, 0x00, 0x00, 0x49, 0x54, 0x66, 0x89, 
0x84, 0x69, 0x83, 0x83, 0x84, 0x68, 0x83, 0x89, 
0x80, 0x72, 0x69, 0x82, 0x08, 0x0B, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 
0x49, 0x54, 0x66, 0x89, 0x84, 0x69, 0x83, 0x83, 
0x84, 0x68, 0x83, 0x89, 0x80, 0x72, 0x69, 0x82, 
0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x0A, 0x00, 0x00, 0x00, 0x49, 0x54, 0x66, 0x89, 
0x84, 0x69, 0x83, 0x83, 0x84, 0x68, 0x83, 0x89, 
0x80, 0x72, 0x69, 0x82, 0x08, 0x11, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 
0x49, 0x54, 0x66, 0x89, 0x84, 0x69, 0x83, 0x83, 
0x84, 0x68, 0x83, 0x89, 0x80, 0x72, 0x69, 0x82, 
0x08, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x0A, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 
0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 
0x54, 0x4C, 0x10, 0x05, 0x8A, 0xC3, 0xDA, 0x8F, 
0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 
0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 
0xFB, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0xAA, 0xAA, 0xAA, 0xAA, 0xDD, 0xDD, 0xDD, 0xDD, 
0xBB, 0xBB, 0xBB, 0xBB, 0xCC, 0xCC, 0xCC, 0xCC, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x1E, 0x00, 0xE8, 0x03, 0x00, 0x00, 
0x0A, 0x00, 0x00, 0x00, 0x49, 0x54, 0x66, 0x89, 
0x84, 0x69, 0x83, 0x83, 0x84, 0x68, 0x83, 0x89, 
0x80, 0x72, 0x69, 0x82};





      #endregion

      // -----------------------------------------------------------------
      // Printing welcome screen and performing startup of Guardant API
      // -----------------------------------------------------------------
      System.Console.WriteLine(" Guardant Stealth/Net III example for C# (MS .NET Environment)\n (C) 2006 Aktiv Co. All rights reserved");

      // Initialize this copy of GrdAPI. GrdStartup() must be called once before first GrdAPI call at application startup
      System.Console.Write("Initialize this copy of GrdAPI : ");
      RetCode = GrdApi.GrdStartup(GrdFMR.Local);    // + GrdFMR.Remote if you want to use network dongles
      ErrorHandling(GrdHandle, RetCode);

      // -----------------------------------------------------------------
      // Creating Grd protected container & returning it's handle
      // -----------------------------------------------------------------
      System.Console.Write("\nCreate Guardant protected container : ");
      GrdHandle = GrdApi.GrdCreateHandle(GrdHandle, GrdCHM.MultiThread);
      if (GrdHandle.Address == 0)                    // Some error found?
      return (int)ErrorHandling(new Handle(0), GrdE.MemoryAllocation);
      ErrorHandling(GrdHandle, GrdE.OK);            // Print success information

      // -----------------------------------------------------------------
      // Store dongle codes in Guardant protected container
      // -----------------------------------------------------------------
      System.Console.Write("\nStoring dongle codes in Guardant protected container : ");
      RetCode = GrdApi.GrdSetAccessCodes(GrdHandle,    // Handle to Guardant protected container
          PublicCode + CryptPU,   // Public code, should always be specified
          ReadCode + CryptRD,     // Private read code; you can omit this code and all following via using of overloaded function;
          WriteCode + CryptWR,    // Private write code; you can omit this code and all following via using of overloaded function;
          MasterCode + CryptMS);  // Private master code; you can omit this code and all following via using of overloaded function;
      ErrorHandling(GrdHandle, RetCode);

      // -----------------------------------------------------------------
      // Set dongle search criteria
      // -----------------------------------------------------------------
      System.Console.Write("\nSetting dongle search conditions : ");
      RemoteMode = GrdFMR.Local;                             // Local dongles only
      DongleFlags = GrdFM.NProg;    // Check by bProg, bVer & dongle type flag
      ProgramNumber = 40;                                     // Check by specified program number                
      DongleID = 0;                                         // This search mode is not used                     
      SerialNumber = 0;                                     // This search mode is not used                     
      Version = 1;                                        // Check by specified version                       
      BitMask = 0;                                         // This search mode is not used                     
      DongleType = GrdDT.GSII64;                            // Dongle that supports GSII64 algorithm   
      DongleModel = GrdFMM.GS3SU;                            // Guardant Stealth III dongle
      DongleInterface = GrdFMI.USB;                           // of any interface

      // All following GrdFind() & GrdLogin() calls before next
      // GrdSetFindMode() will use specified flag values. 
      // If dongle field values and specified values do not match, error code is
      // returned. Both access code and flags are required to call the dongle.
      RetCode = GrdApi.GrdSetFindMode(GrdHandle,
                                      RemoteMode,
                                      DongleFlags,
                                      ProgramNumber,
                                      DongleID,
                                      SerialNumber,
                                      Version,
                                      BitMask,
                                      DongleType,
                                      DongleModel,
                                      DongleInterface);
      ErrorHandling(GrdHandle, RetCode);

      // -----------------------------------------------------------------
      // Search for all specified dongles and print ID's
      // -----------------------------------------------------------------
      System.Console.WriteLine("\nSearching for all specified dongles and print info about it's : ");
      RetCode = GrdApi.GrdFind(GrdHandle, GrdF.First, out DongleID, out FindInfo);
      if (RetCode == GrdE.OK)        // Print table header if at least one dongle found
        System.Console.Write("; Found dongle with following ID : ");
      while (RetCode == GrdE.OK)
      {
        // Print info about dongles found
        System.Console.Write("{0,8:X}", DongleID);                // Dongle's ID (unique)
        // Find next dongle
        RetCode = GrdApi.GrdFind(GrdHandle, GrdF.Next, out DongleID, out FindInfo);
      }
      if (RetCode == GrdE.AllDonglesFound)                        // Search has been completed?
        System.Console.Write("\nDongles search is complete with no errors\n");
      else
        ErrorHandling(GrdHandle, RetCode);

      // -----------------------------------------------------------------
      // Search for the specified local or remote dongle and log in
      // -----------------------------------------------------------------
      System.Console.Write("\nSearching for the specified local or remote dongle and log in : ");
      // If command line parameter is specified, License Management System functions are used
      if (args.Length != 0)
        //LMS = Int32.Parse(args[0]);
        LMS = uint.Parse(args[0]); //VS2012
      else
        //LMS = -1;
        LMS = 0xFFFFFFFF; //VS2012

      // All following Guardant API calls before next GrdCloseHandle()/GrdLogin() will use this dongle
      RetCode = GrdApi.GrdLogin(GrdHandle, (uint)LMS, GrdLM.PerStation);
      ErrorHandling(GrdHandle, RetCode);



      // -----------------------------------------------------------------
      // Generate Question
      // -----------------------------------------------------------------
      byte[] pQuestion = new byte[8]; // буфер, куда будет помещен сгенерированный вопрос.
      uint pdwID;
      uint pdwPublic; // буфер, куда будет помещено численное значение Public code ключа, для которого сгенерирован вопрос.
      byte[] pHash = new byte[8]; // буфер, куда будет помещено значение MAC (Message Authentication Code - кода аутентификации сообщения) для верификации вопроса.


      System.Console.Write("\nGenerating Question : ");
      RetCode = GrdApi.GrdTRU_GenerateQuestion(GrdHandle, out pQuestion, out pdwID, out pdwPublic, out pHash);
      ErrorHandling(GrdHandle, RetCode);

      // -----------------------------------------------------------------
      // Decript Question
      // -----------------------------------------------------------------
      System.Console.Write("\nDecripting Question : ");
      RetCode = GrdApi.GrdTRU_DecryptQuestion(
                                                GrdHandle,
                                                (uint)GrdAN.GSII64,// 
                                                (uint)GrdAN.HASH64, //
                                                pQuestion,
                                                pdwID,
                                                pdwPublic,
                                                pHash);
      ErrorHandling(GrdHandle, RetCode);

      // -----------------------------------------------------------------
      // Encrypt Answer
      // -----------------------------------------------------------------
      int pdwAnswerSize = 1196*3 + 128;
      byte[] pAnswer = new byte[pdwAnswerSize];

      System.Console.Write("\nEncrypting Answer : ");
      RetCode = GrdApi.GrdTRU_EncryptAnswer(GrdHandle, (uint)30, 1169, g_byDongleImage, pQuestion, (uint)GrdAN.GSII64, (uint)GrdAN.HASH64, out pAnswer, out pdwAnswerSize);
      ErrorHandling(GrdHandle, RetCode);

      // -----------------------------------------------------------------
      // Apply Answer
      // -----------------------------------------------------------------
      System.Console.Write("\nApplying Answer : ");
      RetCode = GrdApi.GrdTRU_ApplyAnswer(GrdHandle, pAnswer);
      ErrorHandling(GrdHandle, RetCode);


      //----------------------------------------------------------------------------//
      // -----------------------------------------------------------------
      // Close hGrd handle. Log out from dongle/server & free allocated memory
      // -----------------------------------------------------------------
      System.Console.Write("\nClosing handle: ");
      RetCode = GrdApi.GrdCloseHandle(GrdHandle);
      ErrorHandling(GrdHandle, RetCode);

      // -----------------------------------------------------------------
      // Deinitialize this copy of GrdAPI. 
      // GrdCleanup() must be called after last GrdAPI call before program termination
      // -----------------------------------------------------------------
      System.Console.Write("\nDeinitializing this copy of GrdAPI : ");
      RetCode = GrdApi.GrdCleanup();
      ErrorHandling(GrdHandle, RetCode);

      return (int)GrdE.OK;
    }
      private static GrdE ErrorHandling(Handle hGrd, GrdE nRet)
        {
            // print the result of last executed function
            Console.WriteLine(GrdApi.PrintResult((int)nRet));

            if (nRet != GrdE.OK)
            {
                if (hGrd.Address != 0)    // Perform some cleanup operations if hGrd handle exists
                {
                    // Close hGrd handle, log out from dongle/server, free allocated memory
                    System.Console.Write("Closing handle: ");
                    nRet = GrdApi.GrdCloseHandle(hGrd);
                    Console.WriteLine(GrdApi.PrintResult((int)nRet));
                }

                // Deinitialize this copy of GrdAPI. GrdCleanup() must be called after last GrdAPI call before program termination
                System.Console.Write("Deinitializing this copy of GrdAPI : ");
                nRet = GrdApi.GrdCleanup();
                Console.WriteLine(GrdApi.PrintResult((int)nRet));

                // Terminate application
                Environment.Exit((int)nRet);
            }
            return nRet;
        }
    
  }
}

Ключ TRU для обновления:

0x49, 0x54, 0x66, 0x89, 0x84, 0x69, 0x83, 0x83, 0x84, 0x68, 0x83, 0x89, 0x80, 0x72, 0x69, 0x82

Тут, например, в переменную pAnswer возвращается больше 13000 байт.