шифрование и криптография в 1С
Здравствуйте! Поставлена задача интеграции со сторонним сервисом. Из описания сервиса:
По ответу от сервиса:
Посредство OpenSSL были сгенерирована пара ключей. Данные удается отправить, подписание данных производилось следующим образом:
Собственно вопрос: как расшифровать полученные данные? Метод "DecryptValue" класса "RSACryptoServiceProvider" не поддерживается, а при использовании метода "Decrypt" выходит ошибка
Все запросы в протокол формируются, как POST с параметрами 'json' и 'signature'.
'json' - значение являющееся строкой формата JSON, содержащей свойства в зависимости от
требуемых операций(загрузка, обновление каталога или создание, оформление заказа).
Строка должна быть закодирована двумя функциями:
§ urlencode - URL кодирование строки (не используется при формировании сигнатуры).
§ base64_encode - BASE64 кодирование.
Это названия функций в PHP. В других языках используйте эквиваленты.
Пример на PHP:
$json = urlencode(base64_encode($json))
'signature' - сигнатура, которая формируется за счет подписи закодированной
строки JSON закрытым ключом. Служит для более безопасной идентификации партнера.
Алгоритм шифрования 'sha256WithRSAEncryption'.
Пример на PHP:
$key = openssl_pkey_get_private("file://privkey.pem", "ваш pass");
openssl_pkey_export($key, $priv_key);
openssl_sign($json, $signature, $priv_key, OPENSSL_ALGO_SHA256);
$signature = base64_encode($signature);
Показать'json' - значение являющееся строкой формата JSON, содержащей свойства в зависимости от
требуемых операций(загрузка, обновление каталога или создание, оформление заказа).
Строка должна быть закодирована двумя функциями:
§ urlencode - URL кодирование строки (не используется при формировании сигнатуры).
§ base64_encode - BASE64 кодирование.
Это названия функций в PHP. В других языках используйте эквиваленты.
Пример на PHP:
$json = urlencode(base64_encode($json))
'signature' - сигнатура, которая формируется за счет подписи закодированной
строки JSON закрытым ключом. Служит для более безопасной идентификации партнера.
Алгоритм шифрования 'sha256WithRSAEncryption'.
Пример на PHP:
$key = openssl_pkey_get_private("file://privkey.pem", "ваш pass");
openssl_pkey_export($key, $priv_key);
openssl_sign($json, $signature, $priv_key, OPENSSL_ALGO_SHA256);
$signature = base64_encode($signature);
По ответу от сервиса:
Для расшифровки должен быть реализован следующий алгоритм, например, на языке PHP:
public function jsonDecrypt($json, $privKey)
{
$chunkSize = ceil(1024 / 8);
$output = '';
while ($json)
{
$chunk = substr($json, 0, $chunkSize);
$json = substr($json, $chunkSize);
if (!openssl_private_decrypt($chunk, $decrypted, $privKey))
{
die('Failed to decrypt data');
}
$output .= $decrypted;
}
$output = gzuncompress($output);
return $output;
}
json - зашифрованная строка
privKey - закрытый ключ партнера (строка)
chunkSize - это предельное количество символов, которое можно расшифровать за раз
По данному количеству строка делится и расшифровывается
openssl_private_decrypt - функция для расшифровки (необходимо подключить
расширение openssl)
gzuncompress - функция для разархивации полученной строки
После этой операции вы получите строку формата JSON, с нужной информацией.
Показатьpublic function jsonDecrypt($json, $privKey)
{
$chunkSize = ceil(1024 / 8);
$output = '';
while ($json)
{
$chunk = substr($json, 0, $chunkSize);
$json = substr($json, $chunkSize);
if (!openssl_private_decrypt($chunk, $decrypted, $privKey))
{
die('Failed to decrypt data');
}
$output .= $decrypted;
}
$output = gzuncompress($output);
return $output;
}
json - зашифрованная строка
privKey - закрытый ключ партнера (строка)
chunkSize - это предельное количество символов, которое можно расшифровать за раз
По данному количеству строка делится и расшифровывается
openssl_private_decrypt - функция для расшифровки (необходимо подключить
расширение openssl)
gzuncompress - функция для разархивации полученной строки
После этой операции вы получите строку формата JSON, с нужной информацией.
Посредство OpenSSL были сгенерирована пара ключей. Данные удается отправить, подписание данных производилось следующим образом:
КрПровайдер = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider");
КрПровайдер.FromXmlString(ХМЛТекст); //Закрытый ключ в формате xml
SafeArrayBinХешДляПодписи = SafeИзДвоичных(Хеш); //Перевод двоичных данных в ComSafeArray
SafeArrayBinПодписьДвоичная = КрПровайдер.SignHash(SafeArrayBinХешДляПодписи, "SHA256");
Собственно вопрос: как расшифровать полученные данные? Метод "DecryptValue" класса "RSACryptoServiceProvider" не поддерживается, а при использовании метода "Decrypt" выходит ошибка
Произошла исключительная ситуация (mscorlib): Размер данных для дешифрования превышает максимум для этого модуля, 128 байт
. Размер ComSafeArray для расшифровки составляет 1281
По теме из базы знаний
- Работа с бинарными файлами, форматом ASN1 и криптографией в 1С8
- Криптография и электронная подпись в решениях на 1С
- Алгоритм шифрования AES ECB 128/192/256
- Криптография (шифрование) на эллиптических кривых
- Универсальная выгрузка – загрузка документов, справочников и регистров с возможностью шифрования (криптография в 1С)
Найденные решения
(3) в вашей этой строке первый 128 символов - это как раз то, что нужно отправить в decode, а не всю строку. JSON дальше идет.
В общем код на PHP просто отрезает первые 128 символов, декодирует их, потом распаковывает и возвращает. При этом в переменной $json возвращается переданная строка с 129-го символа и дальше.
ЗЫ: предположу, что где-то выше есть цикл, который вызывается до тех пор, пока json-строка не станет пустой.
ЗЫЗЫ: не, нифига, не увидел выше whie, который ровно то и делает. Т.е. он скармливает decrypted по 128 байт, результат накапливает, потом декомпрессия. Как бы мораль: код форматируйте, а то не видно нифига.
В общем код на PHP просто отрезает первые 128 символов, декодирует их, потом распаковывает и возвращает. При этом в переменной $json возвращается переданная строка с 129-го символа и дальше.
ЗЫ: предположу, что где-то выше есть цикл, который вызывается до тех пор, пока json-строка не станет пустой.
ЗЫЗЫ: не, нифига, не увидел выше whie, который ровно то и делает. Т.е. он скармливает decrypted по 128 байт, результат накапливает, потом декомпрессия. Как бы мораль: код форматируйте, а то не видно нифига.
Остальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(2)Т.е. я должен все-таки json строку получить, верно? Сейчас получаю непонятно что. Возможно, проблемы с кодировкой или это двоичные данные (файл ответа во вложении)
Прикрепленные файлы:
answer.txt
(3) в вашей этой строке первый 128 символов - это как раз то, что нужно отправить в decode, а не всю строку. JSON дальше идет.
В общем код на PHP просто отрезает первые 128 символов, декодирует их, потом распаковывает и возвращает. При этом в переменной $json возвращается переданная строка с 129-го символа и дальше.
ЗЫ: предположу, что где-то выше есть цикл, который вызывается до тех пор, пока json-строка не станет пустой.
ЗЫЗЫ: не, нифига, не увидел выше whie, который ровно то и делает. Т.е. он скармливает decrypted по 128 байт, результат накапливает, потом декомпрессия. Как бы мораль: код форматируйте, а то не видно нифига.
В общем код на PHP просто отрезает первые 128 символов, декодирует их, потом распаковывает и возвращает. При этом в переменной $json возвращается переданная строка с 129-го символа и дальше.
ЗЫ: предположу, что где-то выше есть цикл, который вызывается до тех пор, пока json-строка не станет пустой.
ЗЫЗЫ: не, нифига, не увидел выше whie, который ровно то и делает. Т.е. он скармливает decrypted по 128 байт, результат накапливает, потом декомпрессия. Как бы мораль: код форматируйте, а то не видно нифига.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот