/// <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); }
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); }
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); }
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)); } }
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)); }
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); }