/// <summary> /// Декодирование ASN.1 структуры транспорта. /// </summary> /// /// <param name="data">ASN.1 закодированная структура.</param> /// <param name="transport">ГОСТ Р 34.10 транспорт.</param> /// /// <argnull name="data" /> /// <exception cref="CryptographicException">При ошибках /// декодирования исходной структуры.</exception> public static void DecodeGostKeyTransport(byte[] data, GostKeyTransportObject transport) { if (data == null) { throw new ArgumentNullException("data"); } if (transport == null) { throw new ArgumentNullException("transport"); } try { Asn1BerDecodeBuffer buffer = new Asn1BerDecodeBuffer(data); GostR3410_KeyTransport asnTransport = new GostR3410_KeyTransport(); asnTransport.Decode(buffer); transport.sessionEncryptedKey_ = new GostWrappedKeyObject(); transport.sessionEncryptedKey_._encryptedKey = asnTransport.sessionEncryptedKey.encryptedKey.Value; transport.sessionEncryptedKey_._mac = asnTransport.sessionEncryptedKey.macKey.Value; transport.sessionEncryptedKey_._ukm = asnTransport.transportParameters.ukm.Value; transport.sessionEncryptedKey_._encryptionParamSet = toString(asnTransport.transportParameters.encryptionParamSet); // Для корректной ошибки, а не ArgumentException string algoid = toString( asnTransport.transportParameters.ephemeralPublicKey. algorithm.algorithm); if (algoid.Equals(GostConstants.OID_CP_GOST_R3410EL)) { transport.transportParameters_ = UnpackPublicKeyInfo2001( asnTransport.transportParameters.ephemeralPublicKey); } else if (algoid.Equals(GostConstants.OID_CP_GOST_R3410_12_256) || (algoid.Equals(GostConstants.OID_CP_GOST_R3410_12_512))) { transport.transportParameters_ = UnpackPublicKeyInfo2012( asnTransport.transportParameters.ephemeralPublicKey); } else { throw new CryptographicException( "Resources.Cryptography_ASN1_Decode_Alg " + algoid); } } catch (Exception e) { throw new CryptographicException( "Resources.Cryptography_ASN1_DecodeWithException " + "GostR3410_KeyTransport", e); } }
/// <summary> /// ASN.1 кодирование структуры транспорта. /// </summary> /// /// <param name="transport">ASN.1 транспорт.</param> /// /// <returns>Закодированная структура.</returns> /// /// <argnull name="transport" /> /// <exception cref="CryptographicException">При ошибках /// кодирования исходной структуры.</exception> public static byte[] EncodeGostKeyTransport( GostKeyTransportObject transport) { if (transport == null) { throw new ArgumentNullException("transport"); } GostR3410_KeyTransport asnTransport = new GostR3410_KeyTransport(); Asn1BerEncodeBuffer buffer = new Asn1BerEncodeBuffer(); try { asnTransport.sessionEncryptedKey = new Gost28147_89_EncryptedKey(); asnTransport.sessionEncryptedKey.encryptedKey = new Gost28147_89_Key( transport.sessionEncryptedKey_._encryptedKey); asnTransport.sessionEncryptedKey.macKey = new Gost28147_89_MAC(transport.sessionEncryptedKey_._mac); asnTransport.transportParameters = new GostR3410_TransportParameters(); asnTransport.transportParameters.ukm = new Asn1OctetString(transport.sessionEncryptedKey_._ukm); asnTransport.transportParameters.encryptionParamSet = CreateGost28147_89_ParamSet( transport.sessionEncryptedKey_._encryptionParamSet); if (transport.Transport.TransportParameters.DigestParamSet == "1.2.643.2.2.30.1") { asnTransport.transportParameters.ephemeralPublicKey = PackPublicKeyInfo2001(transport.transportParameters_); } else if (transport.Transport.TransportParameters.DigestParamSet == "1.2.643.7.1.1.2.2") { asnTransport.transportParameters.ephemeralPublicKey = PackPublicKeyInfo2012_256(transport.transportParameters_); } else if (transport.Transport.TransportParameters.DigestParamSet == "1.2.643.7.1.1.2.3") { asnTransport.transportParameters.ephemeralPublicKey = PackPublicKeyInfo2012_512(transport.transportParameters_); } asnTransport.Encode(buffer); } catch (Exception e) { throw new CryptographicException( "Resources.Cryptography_ASN1_EncodeWithException " + "GostR3410_KeyTransport", e); } return(buffer.MsgCopy); }
/// <summary> /// Формирование данных обмена, на основе симметричного /// ключа шифрования сообщения ГОСТ 28147. /// </summary> /// /// <param name="alg">Симметричный ключ ГОСТ 28147.</param> /// <param name="wrapMethod">Алгоритм экпорта</param> /// <returns>Зашифрованные данные для отправки стороне /// получателю.</returns> /// /// <argnull name="alg" /> public GostKeyTransport CreateKeyExchange(SymmetricAlgorithm alg, GostKeyWrapMethod wrapMethod) { if (alg == null) { throw new ArgumentNullException("alg"); } if (wrapMethod != GostKeyWrapMethod.CryptoProKeyWrap && wrapMethod != GostKeyWrapMethod.CryptoPro12KeyWrap) { throw new CryptographicException( string.Format(Properties.Resources.Cryptography_UnsupportedWrapMethod, wrapMethod)); } // Получаем параметры получателя. Gost3410Parameters senderParameters = gostKey_.ExportParameters( false); GostKeyTransportObject transport = new GostKeyTransportObject(); // Создаем эфимерный ключ с параметрами получателя. using (Gost3410_2012_512EphemeralCryptoServiceProvider sender = new Gost3410_2012_512EphemeralCryptoServiceProvider( senderParameters)) { // Создаем распределенный секрет. byte[] wrapped_data; using (GostSharedSecretAlgorithm agree = sender.CreateAgree( senderParameters)) { // Зашифровываем симметричный ключ. wrapped_data = agree.Wrap(alg, wrapMethod); } GostWrappedKeyObject wrapped = new GostWrappedKeyObject(); wrapped.SetByXmlWrappedKey(wrapped_data); transport.sessionEncryptedKey_ = wrapped; transport.transportParameters_ = new Gost3410CspObject(); transport.transportParameters_.Parameters = sender.ExportParameters(false); } return(transport.Transport); }