예제 #1
0
        /// <summary>
        /// Вспомогательная функция для шифрования данных по алгоритму ГОСТ 28147-89
        /// с зацеплением
        /// </summary>
        /// <param name="session">Текущая сессия</param>
        /// <param name="data">Данные для шифрования</param>
        /// <param name="initVector">Синхропосылка</param>
        /// <param name="keyId">Ключ для шифрования</param>
        /// <returns>Зашифрованные данные</returns>
        public static byte[] CBC_Gost28147_89_Encrypt(ISession session, byte[] data,
                                                      byte[] initVector, IObjectHandle keyId)
        {
            // Дополняем данные по ISO 10126
            byte[] dataWithPadding = ISO_10126_Padding.Pad(data, Settings.GOST28147_89_BLOCK_SIZE);

            byte[] round = new byte[Settings.GOST28147_89_BLOCK_SIZE];
            Buffer.BlockCopy(initVector, 0, round, 0, initVector.Length);

            using (var ms = new MemoryStream())
            {
                var mechanism = Settings.Factories.MechanismFactory.Create(CKM.CKM_GOST28147_ECB);

                for (var i = 0; i < dataWithPadding.Length / Settings.GOST28147_89_BLOCK_SIZE; i++)
                {
                    byte[] currentData = new byte[Settings.GOST28147_89_BLOCK_SIZE];
                    Buffer.BlockCopy(dataWithPadding, i * Settings.GOST28147_89_BLOCK_SIZE,
                                     currentData, 0, currentData.Length);
                    byte[] block = round.Xor(currentData);

                    // Получение зашифрованного блока данных
                    byte[] encryptedBlock = session.Encrypt(mechanism, keyId, block);

                    Buffer.BlockCopy(encryptedBlock, 0, round, 0, encryptedBlock.Length);
                    ms.Write(encryptedBlock, 0, encryptedBlock.Length);
                }

                return(ms.ToArray());
            }
        }
예제 #2
0
        static void Main(string[] args)
        {
            try
            {
                // Инициализировать библиотеку
                Console.WriteLine("Library initialization");
                using (var pkcs11 = new Pkcs11(Settings.RutokenEcpDllDefaultPath, Settings.OsLockingDefault))
                {
                    // Получить доступный слот
                    Console.WriteLine("Checking tokens available");
                    Slot slot = Helpers.GetUsableSlot(pkcs11);

                    // Открыть RW сессию в первом доступном слоте
                    Console.WriteLine("Opening RW session");
                    using (Session session = slot.OpenSession(false))
                    {
                        // Выполнить аутентификацию Пользователя
                        Console.WriteLine("User authentication");
                        session.Login(CKU.CKU_USER, SampleConstants.NormalUserPin);

                        try
                        {
                            // Получить данные для шифрования
                            byte[] sourceData = SampleData.Encrypt_Gost28147_89_CBC_SourceData;

                            // Получить ключ для шифрования
                            Console.WriteLine("Getting secret key...");
                            List <ObjectHandle> keys = session.FindAllObjects(SymmetricKeyAttributes);
                            Errors.Check("No keys found", keys.Count > 0);

                            // Выполнить дополнение данных по ISO 10126
                            byte[] dataWithPadding = ISO_10126_Padding.Pad(sourceData, SampleConstants.Gost28147_89_BlockSize);

                            // Получить синхропосылку
                            var    random     = new Random();
                            byte[] initVector = new byte[SampleConstants.Gost28147_89_BlockSize];
                            random.NextBytes(initVector);
                            byte[] round = new byte[SampleConstants.Gost28147_89_BlockSize];
                            Buffer.BlockCopy(initVector, 0, round, 0, initVector.Length);

                            Console.WriteLine("Encrypting...");
                            byte[] encryptedData;
                            using (var ms = new MemoryStream())
                            {
                                // Инициализировать операцию шифрования
                                var mechanism = new Mechanism((uint)Extended_CKM.CKM_GOST28147_ECB);

                                for (var i = 0; i < dataWithPadding.Length / SampleConstants.Gost28147_89_BlockSize; i++)
                                {
                                    byte[] currentData = new byte[SampleConstants.Gost28147_89_BlockSize];
                                    Buffer.BlockCopy(dataWithPadding, i * SampleConstants.Gost28147_89_BlockSize,
                                                     currentData, 0, currentData.Length);
                                    byte[] block = round.Xor(currentData);

                                    // Получение зашифрованного блока данных
                                    byte[] encryptedBlock = session.Encrypt(mechanism, keys[0], block);

                                    Buffer.BlockCopy(encryptedBlock, 0, round, 0, encryptedBlock.Length);
                                    ms.Write(encryptedBlock, 0, encryptedBlock.Length);
                                }

                                encryptedData = ms.ToArray();
                            }

                            // Распечатать буфер, содержащий зашифрованные данные
                            Console.WriteLine(" Encrypting buffer is:");
                            Helpers.PrintByteArray(encryptedData);
                            Console.WriteLine("Encryption has been completed successfully");

                            // Расшифровать данные
                            Console.WriteLine("Decrypting...");

                            round = new byte[SampleConstants.Gost28147_89_BlockSize];
                            Buffer.BlockCopy(initVector, 0, round, 0, initVector.Length);

                            byte[] decryptedData;
                            using (var ms = new MemoryStream())
                            {
                                var mechanism = new Mechanism((uint)Extended_CKM.CKM_GOST28147_ECB);

                                for (var i = 0; i < encryptedData.Length / SampleConstants.Gost28147_89_BlockSize; i++)
                                {
                                    byte[] currentData = new byte[SampleConstants.Gost28147_89_BlockSize];
                                    Buffer.BlockCopy(encryptedData, i * SampleConstants.Gost28147_89_BlockSize,
                                                     currentData, 0, currentData.Length);

                                    // Получение расшифрованного блока данных
                                    byte[] decryptedBlock = session.Decrypt(mechanism, keys[0], currentData);

                                    byte[] decryptedRound = round.Xor(decryptedBlock);
                                    Buffer.BlockCopy(currentData, 0, round, 0, currentData.Length);

                                    ms.Write(decryptedRound, 0, decryptedRound.Length);
                                }

                                // Снимаем дополнение данных
                                decryptedData = ISO_10126_Padding.Unpad(ms.ToArray());
                            }

                            // Распечатать буфер, содержащий расшифрованные данные
                            Console.WriteLine(" Decrypted buffer is:");
                            Helpers.PrintByteArray(decryptedData);
                            Console.WriteLine("Decryption has been completed successfully");

                            // Сравнить исходные данные с расшифрованными
                            bool encryptionState = (Convert.ToBase64String(sourceData) ==
                                                    Convert.ToBase64String(decryptedData));
                            Errors.Check("Source data and decrypted data are not equal", encryptionState);

                            Console.WriteLine("Source data and decrypted data are equal");
                        }
                        finally
                        {
                            // Сбросить права доступа как в случае исключения,
                            // так и в случае успеха.
                            // Сессия закрывается автоматически.
                            session.Logout();
                        }
                    }
                }
            }
            catch (Pkcs11Exception ex)
            {
                Console.WriteLine($"Operation failed [Method: {ex.Method}, RV: {ex.RV}]");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Operation failed [Message: {ex.Message}]");
            }
        }