Ejemplo n.º 1
0
        public static void EndEncrypt(ProviderType providerType, SafeKeyHandleImpl symKeyHandle)
        {
            uint dataLength = 0;
            var  data       = new byte[32];
            var  success    = CryptoApi.CryptEncrypt(symKeyHandle, SafeHashHandleImpl.InvalidHandle, true, 0, data, ref dataLength, (uint)data.Length);

            if (!success)
            {
                throw CreateWin32Error();
            }
        }
Ejemplo n.º 2
0
        public static void EndCrypt(SafeKeyHandleImpl symKeyHandle, Gost28147CryptoTransformMode transformMode)
        {
            bool success;
            uint dataLength = 0;

            if (transformMode == Gost28147CryptoTransformMode.Encrypt)
            {
                var data = new byte[32];
                success = CryptoApi.CryptEncrypt(symKeyHandle, SafeHashHandleImpl.InvalidHandle, true, 0, data, ref dataLength, (uint)data.Length);
            }
            else
            {
                var data = new byte[0];
                success = CryptoApi.CryptDecrypt(symKeyHandle, SafeHashHandleImpl.InvalidHandle, true, 0, data, ref dataLength) || (GostCryptoConfig.ProviderType == ProviderTypes.VipNet);
            }

            if (!success)
            {
                throw CreateWin32Error();
            }
        }
Ejemplo n.º 3
0
        public static int EncryptData(ProviderType providerType, SafeKeyHandleImpl symKeyHandle, byte[] data, int dataOffset, int dataLength, ref byte[] encryptedData, int encryptedDataOffset, PaddingMode paddingMode, bool isDone, bool isStream)
        {
            if (dataOffset < 0)
            {
                throw ExceptionUtility.ArgumentOutOfRange(nameof(dataOffset));
            }

            if (dataLength < 0)
            {
                throw ExceptionUtility.ArgumentOutOfRange(nameof(dataLength));
            }

            if (dataOffset > data.Length)
            {
                throw ExceptionUtility.ArgumentOutOfRange(nameof(dataOffset), Resources.InvalidDataOffset);
            }

            var length = dataLength;

            if (isDone)
            {
                length += 8;
            }

            // Выровненные данные
            var dataAlignLength = (uint)dataLength;
            var dataAlignArray  = new byte[length];

            Array.Clear(dataAlignArray, 0, length);
            Array.Copy(data, dataOffset, dataAlignArray, 0, dataLength);

            if (isDone)
            {
                var dataPadding     = dataLength & 7;
                var dataPaddingSize = (byte)(8 - dataPadding);

                // Добпаление дополнения данных в зависимости от настроек
                switch (paddingMode)
                {
                case PaddingMode.None:
                    if ((dataPadding != 0) && !isStream)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.EncryptInvalidDataSize);
                    }

                    break;

                case PaddingMode.Zeros:
                    if (dataPadding != 0)
                    {
                        dataAlignLength += dataPaddingSize;

                        // Дополнение заполняется нулевыми байтами
                    }

                    break;

                case PaddingMode.PKCS7:
                {
                    dataAlignLength += dataPaddingSize;

                    var paddingIndex = dataLength;

                    // Дополнение заполняется байтами, в каждый из которых записывается размер дополнения
                    while (paddingIndex < dataAlignLength)
                    {
                        dataAlignArray[paddingIndex++] = dataPaddingSize;
                    }
                }
                break;

                case PaddingMode.ANSIX923:
                {
                    dataAlignLength += dataPaddingSize;

                    // Дополнение заполняется нулевыми, кроме последнего - в него записывается размер дополнения
                    dataAlignArray[(int)((IntPtr)(dataAlignLength - 1))] = dataPaddingSize;
                }
                break;

                case PaddingMode.ISO10126:
                {
                    dataAlignLength += dataPaddingSize;

                    // Дополнение заполняется случайными байтами, кроме последнего - в него записывается размер дополнения
                    var randomPadding = new byte[dataPaddingSize - 1];
                    GetRandomNumberGenerator(providerType).GetBytes(randomPadding);
                    randomPadding.CopyTo(dataAlignArray, dataLength);
                    dataAlignArray[(int)((IntPtr)(dataAlignLength - 1))] = dataPaddingSize;
                }
                break;

                default:
                    throw ExceptionUtility.Argument(nameof(paddingMode), Resources.InvalidPaddingMode);
                }
            }

            // Шифрование данных
            if (!CryptoApi.CryptEncrypt(symKeyHandle, SafeHashHandleImpl.InvalidHandle, false, 0, dataAlignArray, ref dataAlignLength, (uint)length))
            {
                throw CreateWin32Error();
            }

            // Копирование результата шифрования данных

            if (encryptedData == null)
            {
                encryptedData = new byte[dataAlignLength];

                Array.Copy(dataAlignArray, 0L, encryptedData, 0L, dataAlignLength);
            }
            else
            {
                if (encryptedDataOffset < 0)
                {
                    throw ExceptionUtility.ArgumentOutOfRange(nameof(encryptedDataOffset));
                }

                if ((encryptedData.Length < dataAlignLength) || ((encryptedData.Length - dataAlignLength) < encryptedDataOffset))
                {
                    throw ExceptionUtility.ArgumentOutOfRange(nameof(encryptedDataOffset), Resources.InvalidDataOffset);
                }

                Array.Copy(dataAlignArray, 0L, encryptedData, encryptedDataOffset, dataAlignLength);
            }

            return((int)dataAlignLength);
        }
Ejemplo n.º 4
0
        public static SafeKeyHandleImpl ImportBulkSessionKey(ProviderType providerType, SafeProvHandleImpl providerHandle, byte[] bulkSessionKey, RNGCryptoServiceProvider randomNumberGenerator)
        {
            if (bulkSessionKey == null)
            {
                throw ExceptionUtility.ArgumentNull(nameof(bulkSessionKey));
            }

            if (randomNumberGenerator == null)
            {
                throw ExceptionUtility.ArgumentNull(nameof(randomNumberGenerator));
            }

            var hSessionKey = SafeKeyHandleImpl.InvalidHandle;

            if (!CryptoApi.CryptGenKey(providerHandle, Constants.CALG_G28147, 0, ref hSessionKey))
            {
                throw CreateWin32Error();
            }

            var keyWrap = new Gost_28147_89_KeyExchangeInfo {
                EncryptedKey = new byte[32]
            };

            Array.Copy(bulkSessionKey, keyWrap.EncryptedKey, 32);
            SetKeyParameterInt32(hSessionKey, Constants.KP_MODE, Constants.CRYPT_MODE_ECB);
            SetKeyParameterInt32(hSessionKey, Constants.KP_ALGID, Constants.CALG_G28147);
            SetKeyParameterInt32(hSessionKey, Constants.KP_PADDING, Constants.ZERO_PADDING);

            uint sessionKeySize = 32;

            if (!CryptoApi.CryptEncrypt(hSessionKey, SafeHashHandleImpl.InvalidHandle, true, 0, keyWrap.EncryptedKey, ref sessionKeySize, sessionKeySize))
            {
                throw CreateWin32Error();
            }

            SetKeyParameterInt32(hSessionKey, Constants.KP_MODE, Constants.CRYPT_MODE_CFB);

            var hashHandle = CreateHashImit(providerHandle, hSessionKey);

            keyWrap.Ukm = new byte[8];
            randomNumberGenerator.GetBytes(keyWrap.Ukm);

            if (!CryptoApi.CryptSetHashParam(hashHandle, Constants.HP_HASHSTARTVECT, keyWrap.Ukm, 0))
            {
                throw CreateWin32Error();
            }

            if (!CryptoApi.CryptHashData(hashHandle, bulkSessionKey, 32, 0))
            {
                throw CreateWin32Error();
            }

            keyWrap.Mac = EndHashData(hashHandle);
            keyWrap.EncryptionParamSet = GetKeyParameterString(hSessionKey, Constants.KP_CIPHEROID);

            SetKeyExchangeExportAlgId(providerType, hSessionKey, Constants.CALG_SIMPLE_EXPORT);
            SetKeyParameterInt32(hSessionKey, Constants.KP_MODE, Constants.CRYPT_MODE_ECB);
            SetKeyParameterInt32(hSessionKey, Constants.KP_PADDING, Constants.ZERO_PADDING);

            return(ImportKeyExchange(providerHandle, keyWrap, hSessionKey));
        }