Beispiel #1
0
        /// <summary>
        /// Шифрует общий секретный ключ.
        /// </summary>
        /// <param name="keyExchangeAlgorithm">Алгоритм шифрации общего секретного ключа.</param>
        /// <exception cref="ArgumentNullException"></exception>
        public GostKeyExchange CreateKeyExchangeInfo(SymmetricAlgorithm keyExchangeAlgorithm)
        {
            if (keyExchangeAlgorithm == null)
            {
                throw ExceptionUtility.ArgumentNull("keyExchangeAlgorithm");
            }

            var keyExchange           = new GostKeyExchange();
            var keyExchangeParameters = _publicKey.ExportParameters(false);

            using (var keyExchangeAsym = new Gost3410EphemeralAsymmetricAlgorithm(keyExchangeParameters))
            {
                byte[] encodedKeyExchangeInfo;

                using (var keyExchangeAlg = keyExchangeAsym.CreateKeyExchange(keyExchangeParameters))
                {
                    encodedKeyExchangeInfo = keyExchangeAlg.EncodeKeyExchange(keyExchangeAlgorithm, GostKeyExchangeExportMethod.CryptoProKeyExport);
                }

                var keyExchangeInfo = new GostKeyExchangeInfo();
                keyExchangeInfo.Decode(encodedKeyExchangeInfo);

                keyExchange.SessionEncryptedKey = keyExchangeInfo;
                keyExchange.TransportParameters = keyExchangeAsym.ExportParameters(false);
            }

            return(keyExchange);
        }
Beispiel #2
0
        private static GostKeyExchangeInfo DecodeSimpleBlob(byte[] exportedKeyBytes)
        {
            if (exportedKeyBytes == null)
            {
                throw ExceptionUtility.ArgumentNull("exportedKeyBytes");
            }

            if (exportedKeyBytes.Length < 16)
            {
                throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA);
            }

            if (BitConverter.ToUInt32(exportedKeyBytes, 4) != Constants.CALG_G28147)
            {
                throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA);
            }

            if (BitConverter.ToUInt32(exportedKeyBytes, 8) != Constants.G28147_MAGIC)
            {
                throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA);
            }

            if (BitConverter.ToUInt32(exportedKeyBytes, 12) != Constants.CALG_G28147)
            {
                throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA);
            }

            var keyExchangeInfo = new GostKeyExchangeInfo();

            var sourceIndex = 16;

            keyExchangeInfo.Ukm = new byte[8];
            Array.Copy(exportedKeyBytes, sourceIndex, keyExchangeInfo.Ukm, 0, 8);
            sourceIndex += 8;

            keyExchangeInfo.EncryptedKey = new byte[32];
            Array.Copy(exportedKeyBytes, sourceIndex, keyExchangeInfo.EncryptedKey, 0, 32);
            sourceIndex += 32;

            keyExchangeInfo.Mac = new byte[4];
            Array.Copy(exportedKeyBytes, sourceIndex, keyExchangeInfo.Mac, 0, 4);
            sourceIndex += 4;

            var encryptionParamSet = new byte[exportedKeyBytes.Length - sourceIndex];

            Array.Copy(exportedKeyBytes, sourceIndex, encryptionParamSet, 0, exportedKeyBytes.Length - sourceIndex);
            keyExchangeInfo.EncryptionParamSet = GostKeyExchangeInfo.DecodeEncryptionParamSet(encryptionParamSet);

            return(keyExchangeInfo);
        }
        /// <summary>
        /// Шифрует общий секретный ключ.
        /// </summary>
        /// <param name="keyExchangeAlgorithm">Алгоритм шифрации общего секретного ключа.</param>
        /// <exception cref="ArgumentNullException"></exception>
        public GostKeyExchange CreateKeyExchangeInfo(SymmetricAlgorithm keyExchangeAlgorithm)
        {
            if (keyExchangeAlgorithm == null)
            {
                throw ExceptionUtility.ArgumentNull("keyExchangeAlgorithm");
            }

            var keyExchange           = new GostKeyExchange();
            var keyExchangeParameters = _publicKey.ExportParameters(false);

            var      digestoid = keyExchangeParameters.DigestParamSet;
            Gost3410 keyExchangeAsym;

            if (digestoid == Constants.OID_GR3411_12_256)
            {
                keyExchangeAsym = new Gost3410_2012_256EphemeralAsymmetricAlgorithm(keyExchangeParameters);
            }
            else if (digestoid == Constants.OID_GR3411_12_512)
            {
                keyExchangeAsym = new Gost3410_2012_512EphemeralAsymmetricAlgorithm(keyExchangeParameters);
            }
            else
            {
                keyExchangeAsym = new Gost3410EphemeralAsymmetricAlgorithm(keyExchangeParameters);
            }

            byte[] encodedKeyExchangeInfo;

            using (var keyExchangeAlg = keyExchangeAsym.CreateKeyExchange(keyExchangeParameters))
            {
                encodedKeyExchangeInfo = keyExchangeAlg.EncodeKeyExchange(keyExchangeAlgorithm, GostKeyExchangeExportMethod.CryptoProKeyExport);
            }

            var keyExchangeInfo = new GostKeyExchangeInfo();

            keyExchangeInfo.Decode(encodedKeyExchangeInfo);

            keyExchange.SessionEncryptedKey = keyExchangeInfo;
            keyExchange.TransportParameters = keyExchangeAsym.ExportParameters(false);

            keyExchangeAsym.Dispose();

            return(keyExchange);
        }
Beispiel #4
0
        private static byte[] EncodeSimpleBlob(GostKeyExchangeInfo keyExchangeInfo)
        {
            if (keyExchangeInfo == null)
            {
                throw ExceptionUtility.ArgumentNull("keyExchangeInfo");
            }

            var encryptionParamSet = GostKeyExchangeInfo.EncodeEncryptionParamSet(keyExchangeInfo.EncryptionParamSet);
            var importedKeyBytes   = new byte[encryptionParamSet.Length + 60];

            var sourceIndex = 0;

            importedKeyBytes[sourceIndex] = 1;
            sourceIndex++;

            importedKeyBytes[sourceIndex] = 32;
            sourceIndex++;
            sourceIndex += 2;

            Array.Copy(BitConverter.GetBytes(Constants.CALG_G28147), 0, importedKeyBytes, sourceIndex, 4);
            sourceIndex += 4;

            Array.Copy(BitConverter.GetBytes(Constants.G28147_MAGIC), 0, importedKeyBytes, sourceIndex, 4);
            sourceIndex += 4;

            Array.Copy(BitConverter.GetBytes(Constants.CALG_G28147), 0, importedKeyBytes, sourceIndex, 4);
            sourceIndex += 4;

            Array.Copy(keyExchangeInfo.Ukm, 0, importedKeyBytes, sourceIndex, 8);
            sourceIndex += 8;

            Array.Copy(keyExchangeInfo.EncryptedKey, 0, importedKeyBytes, sourceIndex, 32);
            sourceIndex += 32;

            Array.Copy(keyExchangeInfo.Mac, 0, importedKeyBytes, sourceIndex, 4);
            sourceIndex += 4;

            Array.Copy(encryptionParamSet, 0, importedKeyBytes, sourceIndex, encryptionParamSet.Length);

            return(importedKeyBytes);
        }
Beispiel #5
0
        private SymmetricAlgorithm DecodeKeyExchangeInternal(byte[] encodedKeyExchangeData, int keyExchangeExportAlgId)
        {
            var keyExchangeInfo = new GostKeyExchangeInfo();

            keyExchangeInfo.Decode(encodedKeyExchangeData);

            SafeKeyHandleImpl symKeyHandle;
            SafeKeyHandleImpl keyExchangeHandle = null;

            try
            {
                keyExchangeHandle = CryptoApiHelper.ImportAndMakeKeyExchange(_provHandle, _keyExchangeParameters, _keyHandle);
                CryptoApiHelper.SetKeyParameterInt32(keyExchangeHandle, Constants.KP_ALGID, keyExchangeExportAlgId);

                symKeyHandle = CryptoApiHelper.ImportKeyExchange(_provHandle, keyExchangeInfo, keyExchangeHandle);
            }
            finally
            {
                keyExchangeHandle.TryDispose();
            }

            return(new Gost28147SymmetricAlgorithm(_provHandle, symKeyHandle));
        }
        public override SymmetricAlgorithm DecodePrivateKey(byte[] encodedKeyExchangeData, GostKeyExchangeExportMethod keyExchangeExportMethod)
        {
            if (encodedKeyExchangeData == null)
            {
                throw ExceptionUtility.ArgumentNull("encodedKeyExchangeData");
            }

            int keyExchangeExportAlgId;

            if (keyExchangeExportMethod == GostKeyExchangeExportMethod.GostKeyExport)
            {
                keyExchangeExportAlgId = Constants.CALG_SIMPLE_EXPORT;
            }
            else if (keyExchangeExportMethod == GostKeyExchangeExportMethod.CryptoProKeyExport)
            {
                keyExchangeExportAlgId = Constants.CALG_PRO_EXPORT;
            }
            else
            {
                throw ExceptionUtility.ArgumentOutOfRange("keyExchangeExportMethod");
            }

            var providerHandle = CryptoApiHelper.ProviderHandle;

            var keyExchangeInfo = new GostKeyExchangeInfo();

            keyExchangeInfo.Decode(encodedKeyExchangeData);

            using (var keyHandle = CryptoApiHelper.DuplicateKey(InternalKeyHandle))
            {
                CryptoApiHelper.SetKeyParameterInt32(keyHandle, Constants.KP_ALGID, keyExchangeExportAlgId);

                var keyExchangeHandle = CryptoApiHelper.ImportKeyExchange(providerHandle, keyExchangeInfo, keyHandle);

                return(new Gost28147SymmetricAlgorithm(providerHandle, keyExchangeHandle));
            }
        }
Beispiel #7
0
        public static SafeKeyHandleImpl ImportBulkSessionKey(SafeProvHandleImpl providerHandle, byte[] bulkSessionKey, RNGCryptoServiceProvider randomNumberGenerator)
        {
            if (bulkSessionKey == null)
            {
                throw ExceptionUtility.ArgumentNull("bulkSessionKey");
            }

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

            var hSessionKey = SafeKeyHandleImpl.InvalidHandle;

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

            var keyWrap = new GostKeyExchangeInfo {
                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);

            SetKeyParameterInt32(hSessionKey, Constants.KP_ALGID, 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));
        }
Beispiel #8
0
        public static SafeKeyHandleImpl ImportKeyExchange(SafeProvHandleImpl providerHandle, GostKeyExchangeInfo keyExchangeInfo, SafeKeyHandleImpl keyExchangeHandle)
        {
            if (keyExchangeInfo == null)
            {
                throw ExceptionUtility.ArgumentNull("keyExchangeInfo");
            }

            var importedKeyBytes = EncodeSimpleBlob(keyExchangeInfo);

            SafeKeyHandleImpl hKeyExchange;

            ImportCspBlob(importedKeyBytes, providerHandle, keyExchangeHandle, out hKeyExchange);

            return(hKeyExchange);
        }