Можно ли объединить несколько состояний SHA1, чтобы получить конечное состояние в Голанге? - PullRequest
2 голосов
/ 03 ноября 2019

В Go1.13 у меня есть сервер загрузки. Этот сервер принимает 2 типа загрузки.

Chunked и Chunked + Threaded . При загрузке по частям все работает ожидаемо. Я вычисляю каждый кусок, пока они пишут на диск. Пользователь может загружать несколько блоков по очереди в хорошем порядке.

Это означает, что я могу сохранить состояние SHA1 каждого блока на диск, используя BinaryMarshaler, затем прочитать предыдущее состояние и продолжить вычислять следующие блоки доЯ нахожу окончательный хэш. Финальный хеш дает мне отлично SHA1 всего файла.

Когда он упорядочен, я могу добавить к существующему состоянию. Но проблема начинается с многопоточности .... (Одновременно)

    hashComplete := sha256.New()
    // read previous sttate from disk
    state, err := ioutil.ReadFile(ctxPath)
    if err != nil {
        return err
    }

    if len(state) > 0 {
        unmarshaler, _ := hashComplete.(encoding.BinaryUnmarshaler)
        if err := unmarshaler.UnmarshalBinary(state); err != nil {
            return err
        }
    }

    // In here im writing file to disk and hash. file object is simple File.
    writer := io.MultiWriter(file, hashComplete)
    n, err := io.Copy(writer, src) // src is source (io.Reader)

    marshaler, _ := hashComplete.(encoding.BinaryMarshaler)
    newState, err := marshaler.MarshalBinary()
    if err != nil {
        return err
    }

    shaCtxFile.Write(newState) // Here im saving last state to disk.

    // Then later, after upload finishes, I read this file and get the SHA1 hex from it. It is correct.

Теперь это чанк-загрузка в определенном / хорошем порядке. Другой метод загрузки - Chunked + Threaded. Это означает, что пользователь может одновременно загружать порции, а затем отправлять запрос на их объединение в заданном порядке (по последнему запросу).

Я уже вычисляю SHA1 каждого порции и сохраняю его на диск.

Мой вопрос : возможно ли объединить эти состояния и получить окончательный хэш, или мне нужно перефразировать после объединения? Есть ли способ объединить эти состояния?

1 Ответ

3 голосов
/ 03 ноября 2019

Предполагая, что вы имеете в виду окончательный хэш для всего файла, тогда нет, вы не можете объединить несколько хешей SHA-1 для частичных данных, чтобы создать хеш для всего файла, как если бы он был вычислен сразу. Причина этого заключается в том, что начальное состояние SHA-1 всегда одинаково, и перефразировка будет перезапущена в этом конкретном состоянии. Кроме того, последний блок дополняется, и перед вычислением окончательного значения хеша добавляется длина (внутренняя по отношению к хеш-функции).

Однако вы, конечно, можете создать список хешей или дерево хешей, где Вы определяете, насколько велики блоки. Затем вы можете хешировать все хеши по чанку, чтобы создать самое верхнее хеш-значение. Теперь у вас есть другое значение хеша, чем просто SHA-1 для файла, но хеш соответствует вашему определению и может быть пересчитан, даже в многопоточном режиме. Он по-прежнему уникален для данных в файле (конечно, при условии последовательного добавления значений хеш-функции), поэтому его можно использовать для проверки целостности файла. И, насколько мне известно, для нормальной защищенной хеш-функции это only способ использования многопоточных хеш-вычислений.

Для получения дополнительной информации, Google о Merkle-trees .


Конечно, SHA-1 был сломан для сопротивления столкновению. К сожалению, это именно то, для чего вы его используете. Поэтому, пожалуйста, используйте SHA-256. Если 256 бит слишком много, тогда использование SHA-256 и выбор левого 160 бит - более безопасная альтернатива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...