public override byte[] ComputeHash(HashAlgorithm hash) { SafeHashHandleImpl hashHandle; if (hash is Gost3411HashAlgorithm) { hashHandle = ((Gost3411HashAlgorithm)hash).InternalHashHandle; } else if (hash is Gost3411Hmac) { hashHandle = ((Gost3411Hmac)hash).InternalHashHandle; } else if (hash is Gost28147ImitHashAlgorithm) { hashHandle = ((Gost28147ImitHashAlgorithm)hash).InternalHashHandle; } else if (hash is Gost3411_2012_256HashAlgorithm) { hashHandle = ((Gost3411_2012_256HashAlgorithm)hash).InternalHashHandle; } else if (hash is Gost3411_2012_512HashAlgorithm) { hashHandle = ((Gost3411_2012_512HashAlgorithm)hash).InternalHashHandle; } else { throw ExceptionUtility.Argument("hash", Resources.RequiredGostHash); } CryptoApiHelper.HashKeyExchange(hashHandle, InternalKeyHandle); return(CryptoApiHelper.EndHashData(hashHandle)); }
private static void ValidateProviderParameters(CspProviderFlags flags) { // Ели информацию о провайдере нужно взять из текущего ключа if ((flags & CspProviderFlags.UseExistingKey) != CspProviderFlags.NoFlags) { const CspProviderFlags notExpectedFlags = CspProviderFlags.UseUserProtectedKey | CspProviderFlags.UseArchivableKey | CspProviderFlags.UseNonExportableKey; if ((flags & notExpectedFlags) != CspProviderFlags.NoFlags) { throw ExceptionUtility.Argument("flags", Resources.InvalidCspProviderFlags); } } // Если пользователь должен сам выбрать ключ (например, в диалоге) if ((flags & CspProviderFlags.UseUserProtectedKey) != CspProviderFlags.NoFlags) { if (!Environment.UserInteractive) { throw ExceptionUtility.CryptographicException(Resources.UserInteractiveNotSupported); } new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand(); } }
private static string GetHashAlgorithmOid(object hashAlg) { string hashAlgOid = null; if (hashAlg is string) { hashAlgOid = GostCryptoConfig.MapNameToOID((string)hashAlg); if (string.IsNullOrEmpty(hashAlgOid)) { hashAlgOid = (string)hashAlg; } } else if (hashAlg is HashAlgorithm) { hashAlgOid = GostCryptoConfig.MapNameToOID(hashAlg.GetType().ToString()); } else if (hashAlg is Type) { hashAlgOid = GostCryptoConfig.MapNameToOID(hashAlg.ToString()); } if (string.IsNullOrEmpty(hashAlgOid)) { throw ExceptionUtility.Argument("hashAlg", Resources.InvalidHashAlgorithm); } return(hashAlgOid); }
public static byte[] DecodeBase64Array(byte[] srcArray) { var num = srcArray.Length / 4; if ((4 * num) != srcArray.Length) { throw ExceptionUtility.Argument("srcArray", Resources.Asn1InvalidEncodedDataLength); } var num2 = 0; var num3 = num; if (srcArray.Length != 0) { if (srcArray[srcArray.Length - 1] == 0x3d) { num2++; num3--; } if (srcArray[srcArray.Length - 2] == 0x3d) { num2++; } } var buffer = new byte[(3 * num) - num2]; var num4 = 0; var num5 = 0; for (var i = 0; i < num3; i++) { var num7 = DecodeBase64Char(srcArray[num4++]); var num8 = DecodeBase64Char(srcArray[num4++]); var num9 = DecodeBase64Char(srcArray[num4++]); var num10 = DecodeBase64Char(srcArray[num4++]); buffer[num5++] = (byte)((num7 << 2) | (num8 >> 4)); buffer[num5++] = (byte)((num8 << 4) | (num9 >> 2)); buffer[num5++] = (byte)((num9 << 6) | num10); } if (num2 != 0) { var num11 = DecodeBase64Char(srcArray[num4++]); var num12 = DecodeBase64Char(srcArray[num4++]); buffer[num5++] = (byte)((num11 << 2) | (num12 >> 4)); if (num2 == 1) { var num13 = DecodeBase64Char(srcArray[num4++]); buffer[num5++] = (byte)((num12 << 4) | (num13 >> 2)); } } return(buffer); }
internal Gost28147SymmetricAlgorithm(SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle) : this() { _provHandle = provHandle.DangerousAddRef(); _keyHandle = CryptoApiHelper.DuplicateKey(keyHandle); if (CryptoApiHelper.GetKeyParameterInt32(_keyHandle, Constants.KP_ALGID) != Constants.CALG_G28147) { throw ExceptionUtility.Argument("keyHandle", Resources.RequiredGost28147); } }
public Gost28147SymmetricAlgorithm(IntPtr provHandle, IntPtr keyHandle) : this() { _provHandle = new SafeProvHandleImpl(provHandle, true); _keyHandle = CryptoApiHelper.DuplicateKey(keyHandle); if (CryptoApiHelper.GetKeyParameterInt32(_keyHandle, Constants.KP_ALGID) != Constants.CALG_G28147) { throw ExceptionUtility.Argument("keyHandle", Resources.RequiredGost28147); } }
internal Gost_28147_89_SymmetricAlgorithm(ProviderType providerType, SafeProvHandleImpl providerHandle, SafeKeyHandleImpl keyHandle) : base(providerType) { InitDefaults(); _providerHandle = providerHandle.DangerousAddRef(); _keyHandle = CryptoApiHelper.DuplicateKey(keyHandle); if (CryptoApiHelper.GetKeyParameterInt32(_keyHandle, Constants.KP_ALGID) != Constants.CALG_G28147) { throw ExceptionUtility.Argument(nameof(keyHandle), Resources.RequiredGost28147); } }
private static int DecodeBase64Char(byte c) { var num = (c < 0x80) ? Base64DecodeTable[c - 40] : -1; if (num < 0) { throw ExceptionUtility.Argument("c", Resources.Asn1IllegalCharacter, c); } return(num); }
public override byte[] ComputeHash(HashAlgorithm hash) { if (!(hash is ISafeHandleProvider <SafeHashHandleImpl> hashHadnleProvider)) { throw ExceptionUtility.Argument(nameof(hash), Resources.RequiredGostHash); } var hashHandle = hashHadnleProvider.SafeHandle; CryptoApiHelper.HashKeyExchange(hashHandle, this.GetSafeHandle()); return(CryptoApiHelper.EndHashData(hashHandle)); }
private static HashAlgorithm CreateHashAlgorithm(object hashAlg) { if (hashAlg == null) { throw ExceptionUtility.ArgumentNull("hashAlg"); } if (!GetHashAlgorithmOid(hashAlg).Equals(Constants.OID_GR3411_12_512, StringComparison.OrdinalIgnoreCase)) { throw ExceptionUtility.Argument("hashAlg", Resources.RequiredGost3411); } HashAlgorithm hashAlgorithm = null; if (_objToHashAlgorithmMethod == null) { lock (ObjToHashAlgorithmMethodSync) { if (_objToHashAlgorithmMethod == null) { var utilsType = Type.GetType("System.Security.Cryptography.Utils"); if (utilsType != null) { _objToHashAlgorithmMethod = utilsType.GetMethod("ObjToHashAlgorithm", BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(object) }, null); } } } } if (_objToHashAlgorithmMethod != null) { try { hashAlgorithm = _objToHashAlgorithmMethod.Invoke(null, new[] { hashAlg }) as HashAlgorithm; } catch (TargetInvocationException exception) { if (exception.InnerException != null) { throw exception.InnerException; } throw; } } return(hashAlgorithm); }
public GostExternalAsymmetricAlgorithm(AsymmetricAlgorithm algorithm) : base(default(ProviderType), algorithm.KeySize) { var createSignatureMethod = algorithm.GetType().GetMethod(nameof(CreateSignature), new[] { typeof(byte[]) }); var verifySignatureMethod = algorithm.GetType().GetMethod(nameof(VerifySignature), new[] { typeof(byte[]), typeof(byte[]) }); if ((createSignatureMethod == null || createSignatureMethod.ReturnType != typeof(byte[])) || (verifySignatureMethod == null || verifySignatureMethod.ReturnType != typeof(bool))) { throw ExceptionUtility.Argument(nameof(algorithm), Resources.ShouldSupportGost3410); } _algorithm = algorithm; _createSignature = hash => (byte[])createSignatureMethod.Invoke(algorithm, new object[] { hash }); _verifySignature = (hash, signature) => (bool)verifySignatureMethod.Invoke(algorithm, new object[] { hash, signature }); }
public override byte[] EncodeKeyExchange(SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod) { if (keyExchangeAlgorithm is Gost28147SymmetricAlgorithm) { return(EncodeKeyExchangeInternal((Gost28147SymmetricAlgorithm)keyExchangeAlgorithm, keyExchangeExportMethod)); } if (keyExchangeAlgorithm is Gost28147SymmetricAlgorithmBase) { using (var gostKeyExchangeAlgorithm = new Gost28147SymmetricAlgorithm()) { return(gostKeyExchangeAlgorithm.EncodePrivateKey((Gost28147SymmetricAlgorithmBase)keyExchangeAlgorithm, keyExchangeExportMethod)); } } throw ExceptionUtility.Argument("keyExchangeAlgorithm", Resources.RequiredGost28147); }
public override byte[] EncodeKeyExchange(SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod) { if (keyExchangeAlgorithm is Gost_28147_89_SymmetricAlgorithm symAlg) { return(EncodeKeyExchangeInternal(symAlg, keyExchangeExportMethod)); } if (keyExchangeAlgorithm is Gost_28147_89_SymmetricAlgorithmBase symAlgBase) { using (var gostKeyExchangeAlgorithm = new Gost_28147_89_SymmetricAlgorithm(symAlgBase.ProviderType)) { return(gostKeyExchangeAlgorithm.EncodePrivateKey(symAlgBase, keyExchangeExportMethod)); } } throw ExceptionUtility.Argument(nameof(keyExchangeAlgorithm), Resources.RequiredGost28147); }
public void ImportCspBlob(byte[] importedKeyBytes) { if (importedKeyBytes == null) { throw ExceptionUtility.ArgumentNull("importedKeyBytes"); } if (!IsPublicKeyBlob(importedKeyBytes)) { throw ExceptionUtility.Argument("importedKeyBytes", Resources.UserImportBulkBlob); } _keyHandleFunc = () => { SafeKeyHandleImpl hKey; _providerParameters.KeyNumber = CryptoApiHelper.ImportCspBlob(importedKeyBytes, _providerHandle, SafeKeyHandleImpl.InvalidHandle, out hKey); return(hKey); }; }
public static Gost_28147_89_SymmetricAlgorithm CreateFromSessionKey(ProviderType providerType, byte[] sessionKey) { if (sessionKey == null) { throw ExceptionUtility.ArgumentNull(nameof(sessionKey)); } if (sessionKey.Length != 32) { throw ExceptionUtility.Argument(nameof(sessionKey), Resources.InvalidHashSize, 32); } var providerHandle = CryptoApiHelper.GetProviderHandle(providerType); var randomNumberGenerator = CryptoApiHelper.GetRandomNumberGenerator(providerType); using (var keyHandle = CryptoApiHelper.ImportBulkSessionKey(providerType, providerHandle, sessionKey, randomNumberGenerator)) { return(new Gost_28147_89_SymmetricAlgorithm(providerType, providerHandle, keyHandle)); } }
public Gost3411Prf(byte[] key, byte[] label, byte[] seed) : this(label, seed) { if (key == null) { throw ExceptionUtility.ArgumentNull("key"); } if (key.Length != 32) { throw ExceptionUtility.Argument("key", Resources.InvalidHashSize); } _hashHmacHandle = SafeHashHandleImpl.InvalidHandle; _buffer = new byte[_labelAndSeed.Length + 32]; using (var keyHandle = CryptoApiHelper.ImportBulkSessionKey(CryptoApiHelper.ProviderHandle, key, CryptoApiHelper.RandomNumberGenerator)) { _key = new Gost28147SymmetricAlgorithm(CryptoApiHelper.ProviderHandle, keyHandle); } }
public void ImportCspBlob(byte[] importedKeyBytes) { if (importedKeyBytes == null) { throw ExceptionUtility.ArgumentNull(nameof(importedKeyBytes)); } if (!IsPublicKeyBlob(importedKeyBytes)) { throw ExceptionUtility.Argument(nameof(importedKeyBytes), Resources.UserImportBulkBlob); } var hProv = CryptoApiHelper.GetProviderHandle(ProviderType); _providerParameters.KeyNumber = CryptoApiHelper.ImportCspBlob(importedKeyBytes, hProv, SafeKeyHandleImpl.InvalidHandle, out var hKey); _providerHandle = hProv; _keyHandle = hKey; _isPublicKeyOnly = 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 int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { if (inputBuffer == null) { throw ExceptionUtility.ArgumentNull(nameof(inputBuffer)); } if (outputBuffer == null) { throw ExceptionUtility.ArgumentNull(nameof(outputBuffer)); } if (inputOffset < 0) { throw ExceptionUtility.ArgumentOutOfRange(nameof(inputOffset)); } if ((inputCount <= 0) || ((inputCount % InputBlockSize) != 0) || (inputCount > inputBuffer.Length)) { throw ExceptionUtility.Argument(nameof(inputOffset), Resources.InvalidDataOffset); } if ((inputBuffer.Length - inputCount) < inputOffset) { throw ExceptionUtility.Argument(nameof(inputOffset), Resources.InvalidDataOffset); } if (_transformMode == Gost_28147_89_CryptoTransformMode.Encrypt) { return(CryptoApiHelper.EncryptData(_providerType, _keyHandle, inputBuffer, inputOffset, inputCount, ref outputBuffer, outputOffset, _paddingValue, false, _isStreamModeValue)); } if ((_paddingValue == PaddingMode.Zeros) || (_paddingValue == PaddingMode.None)) { return(CryptoApiHelper.DecryptData(_keyHandle, inputBuffer, inputOffset, inputCount, ref outputBuffer, outputOffset, _paddingValue, false)); } int dectyptDataLength; if (_dataBuffer == null) { _dataBuffer = new byte[InputBlockSize]; var length = inputCount - InputBlockSize; Array.Copy(inputBuffer, inputOffset + length, _dataBuffer, 0, InputBlockSize); dectyptDataLength = CryptoApiHelper.DecryptData(_keyHandle, inputBuffer, inputOffset, length, ref outputBuffer, outputOffset, _paddingValue, false); } else { CryptoApiHelper.DecryptData(_keyHandle, _dataBuffer, 0, _dataBuffer.Length, ref outputBuffer, outputOffset, _paddingValue, false); outputOffset += OutputBlockSize; var length = inputCount - InputBlockSize; Array.Copy(inputBuffer, inputOffset + length, _dataBuffer, 0, InputBlockSize); dectyptDataLength = OutputBlockSize + CryptoApiHelper.DecryptData(_keyHandle, inputBuffer, inputOffset, length, ref outputBuffer, outputOffset, _paddingValue, false); } return(dectyptDataLength); }