Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline vasiliy78  
#1 Оставлено : 15 ноября 2018 г. 16:09:33(UTC)
vasiliy78

Статус: Новичок

Группы: Участники
Зарегистрирован: 28.09.2018(UTC)
Сообщений: 6

Поблагодарили: 4 раз в 2 постах
Добрый день!

Пытаюсь написать сервис, который отправляет soap-запрос на сервис ФСС и получает оттуда больничный лист.
Уже написал запрос, который подписывается ЭЦП, отправляется на тестовый сервер ФСС и приходит корректный ответ(данные по больничному листку)

Но с шифрованием все оказалось не однозначно.
ВО первых, в самой спецификации, указанной на сайте ФСС про шифрование почти ничего не написано, кроме как данные должны быть зашифрованы по ГОСТ 28147-89.
Например, не указано в каком режиме шифровать данные(ECB, CBC и др.), как сформировать UKM(синхропосылку), какой паддинг использовать и т.д.

Посмотрев этот форум нашел информацию о том, что шифровать нужно в режиме CBC и используя паддинг ISO10126
ссылка на пост

Я пишу на python и использую библиотеку pygost, т.к. не хочу использовать microsoft CryptoApi для работы с криптопровайдером, т.к. придется описывать кучу С-шных структур на питоне.

Сейчас я делаю так(весь алгоритм), который не использует Microsoft Crypto Api:

1.Случайным образом вырабатываю сессионный ключ и вектор инициализации(IV), и синхропосылку – UKM.
2.Генерирую эфемерную ключевую пару(тоже случайным образом)
3.Выполняю выработку общего ключа(ключ согласования - kek) используя приватный ключ эфемерной пары, открытый ключ ФСС и UKM-синхропосылку, работая с 34.10-2001 кривой
4.Шифрую данные сессионного ключа в режиме ECB используя ключ согласования - KEK и UKM – получаю зашифрованный сессионный ключ и MAC
5.Делаю падинг исходных данных(паддинг первого запроса в ФСС, который подписан и работает) в соответствии с ISO10126.
6.Шифрую сырые данные в режиме CBC используя не зашифрованный сессионный ключ и вектор инициализации – IV
7.Формирую структуру GostR3410-KeyTransport из полученных данных при шифровании сессионного ключа.
8.Формирую итоговую XML для soap-запроса

В итоге сначала у меня была такая ошибка:
«S:Serverru.ibs.cryptoprto.jcp.wrapper.eln.ws.client.generated.CryptoException_Exception: Не удалось расшифровать сообщение. Возможно сообщение зашифровано на ключе отличном от ключа уполномоченного лица ФСС. Проверьте правильность и актуальность ключа уполномоченного лица ФСС.»

Это потому что я попробовал везде использовать режим шифрования CBC(т.е. и для шифрования сессионого ключа тоже), но изменив режим шифрования сессионного ключа на ECB, ошибка эта ушла, но появилась новая:
«Запрос не корректен. Код ошибки - 500. S:Serverru.ibs.cryptoprto.jcp.wrapper.eln.ws.client.generated.CryptoException_Exception: Error in execution of data encrypting/decrypting operation. class org.apache.xml.security.encryption.XMLEncryptionException»

Из чего я сделал вывод, что зашифрованный сессионный ключ теперь расшифрован, но не получается расшифровать сами данные. Возможно я ошибаюсь.

В указанном выше посте написано в каком режиме шифруются данные, но в каком сессионный ключ - нет.

Вопросы такие:
1.В каком режиме шифровать сырые данные(данные первого запроса с подписью)? (я использовал CBC, padding ISO10126)
2.В каком режиме шифровать сессионный ключ? (я использовал ECB)
3.Каким образом формировать UKM? Можно ли его формировать случайно, чтобы потом вставить в структуру GostR3410-KeyTransport?
4.Можно ли генерировать сессионный ключ и вектор инициализации случайно?

thanks 2 пользователей поблагодарили vasiliy78 за этот пост.
_Nikolay оставлено 16.02.2019(UTC), Baki111 оставлено 22.02.2023(UTC)
Offline vasiliy78  
#2 Оставлено : 4 декабря 2018 г. 11:55:04(UTC)
vasiliy78

Статус: Новичок

Группы: Участники
Зарегистрирован: 28.09.2018(UTC)
Сообщений: 6

Поблагодарили: 4 раз в 2 постах
В общем разобрался сам:
Ответы на вопросы такие:
1. Режим шифрования данных CBC, padding ISO10126, следует еще упоминуть что тут еще используется алгоритм усложнения ключей
2. ECB
3. Можно случайно, работает.
4. Можно
thanks 2 пользователей поблагодарили vasiliy78 за этот пост.
Русев Андрей оставлено 04.12.2018(UTC), Baki111 оставлено 22.02.2023(UTC)
Offline Baki111  
#3 Оставлено : 27 марта 2023 г. 13:21:19(UTC)
Baki111

Статус: Участник

Группы: Участники
Зарегистрирован: 09.12.2022(UTC)
Сообщений: 22
Российская Федерация

Сказал(а) «Спасибо»: 8 раз
Добрый день!
Занимаюсь такой же задачей. Работаю на таком же стеке: Ubuntu, Python, PyGost.

На тестовом контуре без шифрования всё работает без проблем.

На тестовом с шифрованием приходит ошибка: "Не удалось расшифровать сообщение. Возможно сообщение зашифровано на ключе отличном от ключа уполномоченного лица ФСС. Проверьте правильность и актуальность ключа уполномоченного лица ФСС."

Перепробовал все опубликованные на данный момент сертификаты ФСС.
Многократно перепробовал разные комбинации параметров, пока всё в молоко.

Проштудировал практически все темы форума на эту тему. Порядок действий такой же как в #1.

Подозреваю, что неправильно формирую структуру GostR3410-KeyTransport.
Код такой (напомню, использую PyGost):

Код:
def gostr3410_key_transport(cek_enc: bytes, mac: bytes, ukm: bytes, pub_ephemeral: bytes) -> str:
    """Создание структуры GostR3410-KeyTransport

    :param cek_enc: Зашифрованный сессионный ключ симметричного шифрования данных
    :type cek_enc: bytes
    :param mac: MAC сессионного ключа
    :type mac: bytes
    :param ukm: UserKeyMaterial, сгенерированный случайно
    :type ukm: bytes
    :param pub_ephemeral: Публичный ключ эфемерной пары, сгенерированный на основе закрытого ключа
    :type pub_ephemeral: bytes
    :return: Структура GostR3410-KeyTransport - байт-код в DER-формате, закодированный в Base64
    :rtype: str
    """

    cek_enc_octet = Gost2814789Key(cek_enc)
    mak_octet = Gost2814789MAC(mac)

    encrypted_key = Gost2814789EncryptedKey()
    encrypted_key['encryptedKey'] = cek_enc_octet
    encrypted_key['macKey'] = mak_octet

    algorithm = AlgorithmIdentifier()
    algorithm['algorithm'] = ObjectIdentifier('1.2.643.7.1.1.1.1')
    algorithm['parameters'] = Any(Null())

    pub_ephemeral_bitstring = BitString(pub_ephemeral)

    ephemeralPublicKey = SubjectPublicKeyInfo(impl=tag_ctxc(0), optional=True)
    ephemeralPublicKey['algorithm'] = algorithm
    ephemeralPublicKey['subjectPublicKey'] = pub_ephemeral_bitstring

    ukm_octet = OctetString(ukm)
    transport_parameters = GostR34102001TransportParameters(impl=tag_ctxc(0), optional=True)
    transport_parameters['encryptionParamSet'] = ObjectIdentifier('1.2.643.7.1.2.1.1.2')
    transport_parameters['ephemeralPublicKey'] = ephemeralPublicKey
    transport_parameters['ukm'] = ukm_octet

    structure = GostR3410KeyTransport()
    structure['sessionEncryptedKey'] = encrypted_key
    structure['transportParameters'] = transport_parameters

    b_structure = structure.encode()
    base64_structure = b64encode(b_structure).decode('utf-8')

    return base64_structure



Я вставил эту строку Base64 в онлайн-ASN.1-декодер, и результат вот такой:

Код:
SEQUENCE {
   SEQUENCE {
      OCTETSTRING a0e8c65197af5fe2b0fe38519f51246d9c8aa1d3dc93cd4dca0ce5ab9f1a5b95
      OCTETSTRING 188e9b08
   }
   [0] {
      OBJECTIDENTIFIER 1.2.643.7.1.2.1.1.2
      [0] {
         SEQUENCE {
            OBJECTIDENTIFIER 1.2.643.7.1.1.1.1
            NULL 
         }
         BITSTRING 0xcb1f988917de18f08e78f989d459d976e1a4771c207b7b77d04996d89e7416ab4d3558612f56d2238701c098bd3e1cfd34ab3d3bbf5caf1e3a1798f4a1f6d519 : 0 unused bit(s)
      }
      OCTETSTRING b3334e27c5c76f7d
   }
}



Сама библиотека PyGost визуализирует получаемый объект более подробно (OID'ы отличаются, потому что уже и их начал перебирать; объекты из разных запросов):

Код:
GostR3410KeyTransport SEQUENCE[
    sessionEncryptedKey: Gost2814789EncryptedKey SEQUENCE[
        encryptedKey: Gost2814789Key OCTET STRING 32 bytes 07094633121737be3dc2a6c6049e67a875e3c876efdd922e68ccc7c25bf580cd;
        macKey: Gost2814789MAC OCTET STRING 4 bytes 9e09e950
    ];
    transportParameters: [0] GostR34102001TransportParameters SEQUENCE OPTIONAL[
        encryptionParamSet: OBJECT IDENTIFIER 1.2.643.7.1.2.5.1.1;
        ephemeralPublicKey: [0] SubjectPublicKeyInfo SEQUENCE OPTIONAL[
            algorithm: AlgorithmIdentifier SEQUENCE[
                algorithm: OBJECT IDENTIFIER 1.2.643.7.1.1.6.1;
                parameters: ANY NULL OPTIONAL
            ];
            subjectPublicKey: BIT STRING 512 bits b785c90eb06160061276ac0ebed257bf680f74ccf6f0476c67ef71922d65f95781648b0097283dfa11e5a1303ac9a00dc19e2b1aa40a3027230973524634b665
        ];
        ukm: OCTET STRING 8 bytes 91275a6435733816
    ]
]


Правильно ли у меня получается? У кого есть возможность, сравните пожалуйста со своей структурой.

Отредактировано пользователем 27 марта 2023 г. 14:05:11(UTC)  | Причина: Не указана

RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.