public static byte[] GetKeyParameter(SafeKeyHandleImpl keyHandle, uint keyParamId) { uint dataLength = 0; if (!CryptoApi.CryptGetKeyParam(keyHandle, keyParamId, null, ref dataLength, 0)) { throw CreateWin32Error(); } var dataBytes = new byte[dataLength]; if (!CryptoApi.CryptGetKeyParam(keyHandle, keyParamId, dataBytes, ref dataLength, 0)) { throw CreateWin32Error(); } return(dataBytes); }
private static SafeHashHandleImpl CreateHashHMAC(SafeProvHandleImpl providerHandle, SafeKeyHandleImpl symKeyHandle, int hmacAlgId) { var hashHmacHandle = SafeHashHandleImpl.InvalidHandle; if (!CryptoApi.CryptCreateHash(providerHandle, (uint)hmacAlgId, symKeyHandle, 0, ref hashHmacHandle)) { var errorCode = Marshal.GetLastWin32Error(); if (errorCode == Constants.NTE_BAD_ALGID) { throw ExceptionUtility.CryptographicException(Resources.AlgorithmNotAvailable); } throw ExceptionUtility.CryptographicException(errorCode); } return(hashHmacHandle); }
public static byte[] EndHashData(SafeHashHandleImpl hashHandle) { uint dataLength = 0; if (!CryptoApi.CryptGetHashParam(hashHandle, Constants.HP_HASHVAL, null, ref dataLength, 0)) { throw CreateWin32Error(); } var data = new byte[dataLength]; if (!CryptoApi.CryptGetHashParam(hashHandle, Constants.HP_HASHVAL, data, ref dataLength, 0)) { throw CreateWin32Error(); } return(data); }
public static SafeProvHandleImpl AcquireProvider(CspParameters providerParameters) { var providerHandle = SafeProvHandleImpl.InvalidHandle; var dwFlags = Constants.CRYPT_VERIFYCONTEXT; if ((providerParameters.Flags & CspProviderFlags.UseMachineKeyStore) != CspProviderFlags.NoFlags) { dwFlags |= Constants.CRYPT_MACHINE_KEYSET; } if (!CryptoApi.CryptAcquireContext(ref providerHandle, providerParameters.KeyContainerName, providerParameters.ProviderName, (uint)providerParameters.ProviderType, dwFlags)) { throw CreateWin32Error(); } return(providerHandle); }
public static int GetKeyParameterInt32(SafeKeyHandleImpl keyHandle, uint keyParamId) { const int doubleWordSize = 4; uint dwDataLength = doubleWordSize; var dwDataBytes = new byte[doubleWordSize]; if (!CryptoApi.CryptGetKeyParam(keyHandle, keyParamId, dwDataBytes, ref dwDataLength, 0)) { throw CreateWin32Error(); } if (dwDataLength != doubleWordSize) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } return(BitConverter.ToInt32(dwDataBytes, 0)); }
private static void SetHashValue(SafeHashHandleImpl hashHandle, byte[] hashValue) { uint hashLength = 0; if (!CryptoApi.CryptGetHashParam(hashHandle, Constants.HP_HASHVAL, null, ref hashLength, 0)) { throw CreateWin32Error(); } if (hashValue.Length != hashLength) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_HASH); } if (!CryptoApi.CryptSetHashParam(hashHandle, Constants.HP_HASHVAL, hashValue, 0)) { throw CreateWin32Error(); } }
public static SafeKeyHandleImpl GenerateDhEphemeralKey(ProviderType providerType, SafeProvHandleImpl providerHandle, int algId, string digestParamSet, string publicKeyParamSet) { var keyHandle = SafeKeyHandleImpl.InvalidHandle; var dwFlags = MapCspKeyFlags(CspProviderFlags.NoFlags) | Constants.CRYPT_PREGEN; if (!CryptoApi.CryptGenKey(providerHandle, (uint)algId, dwFlags, ref keyHandle)) { throw CreateWin32Error(); } if (!providerType.IsVipNet()) { SetKeyParameterString(keyHandle, Constants.KP_HASHOID, digestParamSet); } SetKeyParameterString(keyHandle, Constants.KP_DHOID, publicKeyParamSet); SetKeyParameter(keyHandle, Constants.KP_X, null); return(keyHandle); }
public static SafeHashHandleImpl CreateHashHmac(SafeProvHandleImpl providerHandle, SafeKeyHandleImpl symKeyHandle) { var hashHmacHandle = SafeHashHandleImpl.InvalidHandle; var hmacAlgId = (GostCryptoConfig.ProviderType == ProviderTypes.VipNet) ? Constants.CALG_GR3411_HMAC34 : Constants.CALG_GR3411_HMAC; if (!CryptoApi.CryptCreateHash(providerHandle, (uint)hmacAlgId, symKeyHandle, 0, ref hashHmacHandle)) { var errorCode = Marshal.GetLastWin32Error(); if (errorCode == Constants.NTE_BAD_ALGID) { throw ExceptionUtility.CryptographicException(Resources.AlgorithmNotAvailable); } throw ExceptionUtility.CryptographicException(errorCode); } return(hashHmacHandle); }
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(); } }
public static int OpenProvider(CspParameters providerParameters, ref SafeProvHandleImpl hProv) { uint dwFlags = MapCspProviderFlags(providerParameters.Flags); if (!CryptoApi.CryptAcquireContext(ref hProv, providerParameters.KeyContainerName, providerParameters.ProviderName, (uint)providerParameters.ProviderType, dwFlags)) { return(Marshal.GetLastWin32Error()); } return(0); //var providerHandle = SafeProvHandleImpl.InvalidHandle; //var dwFlags = MapCspProviderFlags(providerParameters.Flags); //if (!CryptoApi.CryptAcquireContext(ref providerHandle, providerParameters.KeyContainerName, providerParameters.ProviderName, (uint)providerParameters.ProviderType, dwFlags)) //{ // throw CreateWin32Error(); //} //return providerHandle; }
public static byte[] SignValue(SafeProvHandleImpl providerHandle, SafeHashHandleImpl hashHandle, int keyNumber, byte[] hashValue) { SetHashValue(hashHandle, hashValue); uint signatureLength = 0; // Вычисление размера подписи if (!CryptoApi.CryptSignHash(hashHandle, (uint)keyNumber, null, 0, null, ref signatureLength)) { throw CreateWin32Error(); } var signatureValue = new byte[signatureLength]; // Вычисление значения подписи if (!CryptoApi.CryptSignHash(hashHandle, (uint)keyNumber, null, 0, signatureValue, ref signatureLength)) { throw CreateWin32Error(); } return(signatureValue); }
public static byte[] SignValue(SafeProvHandleImpl hProv, int keyNumber, byte[] hashValue) { using (var hashHandle = SetupHashAlgorithm(hProv, hashValue)) { uint signatureLength = 0; // Вычисление размера подписи if (!CryptoApi.CryptSignHash(hashHandle, (uint)keyNumber, null, 0, null, ref signatureLength)) { throw CreateWin32Error(); } var signatureValue = new byte[signatureLength]; // Вычисление значения подписи if (!CryptoApi.CryptSignHash(hashHandle, (uint)keyNumber, null, 0, signatureValue, ref signatureLength)) { throw CreateWin32Error(); } return(signatureValue); } }
public static byte[] SignValue(SafeProvHandleImpl hProv, int keyNumber, byte[] hashValue, GostAlgorithmType alg) { using (var hashHandle = SetupHashAlgorithm(hProv, hashValue, alg)) { int signatureLength = 0; // Вычисление размера подписи if (!CryptoApi.CryptSignHash(hashHandle, (int)keyNumber, null, 0, null, ref signatureLength)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var signatureValue = new byte[signatureLength]; // Вычисление значения подписи if (!CryptoApi.CryptSignHash(hashHandle, (int)keyNumber, null, 0, signatureValue, ref signatureLength)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(signatureValue); } }
private static SafeHashHandleImpl SetupHashAlgorithm(SafeProvHandleImpl providerHandle, byte[] hashValue) { var hashHandle = CreateHash_3411_94(providerHandle); uint hashLength = 0; if (!CryptoApi.CryptGetHashParam(hashHandle, Constants.HP_HASHVAL, null, ref hashLength, 0)) { throw CreateWin32Error(); } if (hashValue.Length != hashLength) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_HASH); } if (!CryptoApi.CryptSetHashParam(hashHandle, Constants.HP_HASHVAL, hashValue, 0)) { throw CreateWin32Error(); } return(hashHandle); }
/// <summary> /// Возвращает сертификат X.509 для указанного ключа. /// </summary> /// <param name="keyHandle">Дескриптор ключа сертификата.</param> public static X509Certificate2 GetKeyCertificate(SafeKeyHandleImpl keyHandle) { uint certDataLength = 0; if (!CryptoApi.CryptGetKeyParam(keyHandle, Constants.KP_CERTIFICATE, null, ref certDataLength, 0)) { if (Marshal.GetLastWin32Error() != Constants.ERROR_NO_SUCH_CERTIFICATE) { throw CreateWin32Error(); } return(null); } var certData = new byte[certDataLength]; if (!CryptoApi.CryptGetKeyParam(keyHandle, Constants.KP_CERTIFICATE, certData, ref certDataLength, 0)) { throw CreateWin32Error(); } return(new X509Certificate2(certData)); }
public static void SetProviderParameter(SafeProvHandleImpl providerHandle, int keyNumber, uint keyParamId, IntPtr keyParamValue) { if ((keyParamId == Constants.PP_KEYEXCHANGE_PIN) || (keyParamId == Constants.PP_SIGNATURE_PIN)) { if (keyNumber == Constants.AT_KEYEXCHANGE) { keyParamId = Constants.PP_KEYEXCHANGE_PIN; } else if (keyNumber == Constants.AT_SIGNATURE) { keyParamId = Constants.PP_SIGNATURE_PIN; } else { throw ExceptionUtility.NotSupported(Resources.KeyAlgorithmNotSupported); } } if (!CryptoApi.CryptSetProvParam(providerHandle, keyParamId, keyParamValue, 0)) { throw CreateWin32Error(); } }
private static SafeHashHandleImpl SetupHashAlgorithm(SafeProvHandleImpl providerHandle, byte[] hashValue, GostAlgorithmType alg) { SafeHashHandleImpl hashHandle; if (alg == GostAlgorithmType.Gost2012_256) { hashHandle = CreateHash_3411_2012_256(providerHandle); } else if (alg == GostAlgorithmType.Gost2012_512) { hashHandle = CreateHash_3411_2012_512(providerHandle); } else { hashHandle = CreateHash_3411_94(providerHandle); } //uint hashLength = 0; //if (!CryptoApi.CryptGetHashParam(hashHandle, Constants.HP_HASHVAL, null, ref hashLength, 0)) //{ // throw CreateWin32Error(); //} //if (hashValue.Length != hashLength) //{ // throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_HASH); //} if (!CryptoApi.CryptSetHashParam(hashHandle, Constants.HP_HASHVAL, hashValue, 0)) { throw CreateWin32Error(); } return(hashHandle); }
protected override bool ReleaseHandle() { CryptoApi.CryptDestroyHash(handle); return(true); }
public static int DecryptData(SafeKeyHandleImpl symKeyHandle, byte[] data, int dataOffset, int dataLength, ref byte[] decryptedData, int decryptedDataOffset, PaddingMode paddingMode, bool isDone) { if (dataOffset < 0) { throw ExceptionUtility.ArgumentOutOfRange(nameof(dataOffset)); } if (dataLength < 0) { throw ExceptionUtility.ArgumentOutOfRange(nameof(dataLength)); } if ((dataOffset > data.Length) || ((dataOffset + dataLength) > data.Length)) { throw ExceptionUtility.ArgumentOutOfRange(nameof(dataOffset), Resources.InvalidDataOffset); } // Выровненные данные var dataAlignLength = (uint)dataLength; var dataAlign = new byte[dataAlignLength]; Array.Copy(data, dataOffset, dataAlign, 0L, dataAlignLength); // Расшифровка данных if (!CryptoApi.CryptDecrypt(symKeyHandle, SafeHashHandleImpl.InvalidHandle, false, 0, dataAlign, ref dataAlignLength)) { throw CreateWin32Error(); } var length = (int)dataAlignLength; if (isDone) { byte dataPaddingSize = 0; // Удаление дополнения данных в зависимости от настроек if (((paddingMode == PaddingMode.PKCS7) || (paddingMode == PaddingMode.ANSIX923)) || (paddingMode == PaddingMode.ISO10126)) { if (dataAlignLength < 8) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } // Размер дополнения находится в последнем байте dataPaddingSize = dataAlign[(int)((IntPtr)(dataAlignLength - 1))]; if (dataPaddingSize > 8) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } // Проверка корректности дополнения данных if (paddingMode == PaddingMode.PKCS7) { for (var paddingIndex = dataAlignLength - dataPaddingSize; paddingIndex < (dataAlignLength - 1); paddingIndex++) { if (dataAlign[paddingIndex] != dataPaddingSize) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } } } else if (paddingMode == PaddingMode.ANSIX923) { for (var paddingIndex = dataAlignLength - dataPaddingSize; paddingIndex < (dataAlignLength - 1); paddingIndex++) { if (dataAlign[paddingIndex] != 0) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } } } } else if ((paddingMode != PaddingMode.None) && (paddingMode != PaddingMode.Zeros)) { throw ExceptionUtility.Argument(nameof(paddingMode), Resources.InvalidPaddingMode); } length -= dataPaddingSize; } if (decryptedData == null) { decryptedData = new byte[length]; Array.Copy(dataAlign, 0, decryptedData, 0, length); } else { if (decryptedDataOffset < 0) { throw ExceptionUtility.ArgumentOutOfRange(nameof(decryptedDataOffset)); } if ((decryptedData.Length < length) || ((decryptedData.Length - length) < decryptedDataOffset)) { throw ExceptionUtility.ArgumentOutOfRange(nameof(decryptedData), Resources.InvalidDataOffset); } Array.Copy(dataAlign, 0, decryptedData, decryptedDataOffset, length); } return(length); }
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); }
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)); }
public static bool VerifySign(SafeProvHandleImpl providerHandle, SafeHashHandleImpl hashHandle, SafeKeyHandleImpl keyHandle, byte[] hashValue, byte[] signatureValue) { SetHashValue(hashHandle, hashValue); return(CryptoApi.CryptVerifySignature(hashHandle, signatureValue, (uint)signatureValue.Length, keyHandle, null, 0)); }