Little endian данные и ша 256 - PullRequest
5 голосов
/ 07 июня 2011

Мне нужно сгенерировать sha256 хешей данных в формате с прямым порядком байтов. Я хотел бы знать, должен ли я сначала преобразовать его в big endian, прежде чем использовать алгоритм sha 256. Или, если алгоритм является «не зависящим от порядка байтов».

РЕДАКТИРОВАТЬ: Извините, я думаю, что я не был ясен. Я хотел бы знать следующее: алгоритм sha256 требует заполнения конца сообщения определенными битами. Первый шаг - добавить 1 в конце сообщения. Затем дополнить его нулями до конца. В самом конце вы должны добавить длину сообщения в битах. То, что я хотел бы знать, может ли это заполнение быть выполнено с прямым порядком байтов. Например, для 640-битного сообщения я мог бы написать последнее слово как 0x280 (с прямым порядком байтов) или 0x8002000 (с прямым порядком байтов). Можно ли сделать это заполнение в порядке с прямым порядком байтов?

Ответы [ 3 ]

6 голосов
/ 11 декабря 2012

SHA256 является не зависящим от порядка байтов, если все, что вам нужно, это хороший хеш.Но если вы пишете SHA256 и хотите получить те же результаты с правильной реализацией, то вы должны играть в игры на оборудовании с прямым порядком байтов.SHA256 сочетает в себе арифметическое сложение (мод 2 * 32) и булеву операцию, поэтому внутренне не зависит от порядка байтов.

2 голосов
/ 24 августа 2016

Позвольте мне ответить относительно sha 256, а также sha 512. Вкратце: сам алгоритм не зависит от порядка байтов.Чувствительные элементы к порядку байтов - это когда данные импортируются из байтового буфера в рабочие переменные алгоритма и когда они экспортируются обратно в результат дайджеста - также байтовый буфер.Если импорт / экспорт включает в себя кастинг, то порядок байтов имеет значение.

Где может произойти приведение: в ша 512 есть рабочий буфер 128 байт.В моем коде это определено так:

    union
    {
        U64   w [80]; (see U64 example below)
        byte  buffer [128];
    };

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

Лучшим способом было бы подготовить макрос get, который берет каждый байт и помещает его на правильное место в типе u64.

КогдаАлгоритм завершен, дайджест-результат выводится из рабочих переменных в некоторый байтовый буфер, если это делается с помощью memcpy, его также нужно будет поменять местами.

При реализации sha 512 может произойти другое приведение типов, которое предназначено для64-битные машины - на 32-битных машинах.В моем случае у меня есть 64-битный тип, который определен:

    typedef struct {
        uint high;
        uint low;
    } U64;

Предположим, я также определил его для байтов с прямым порядком байтов, как показано ниже:

    typedef struct {
        uint low;
        uint high;
    } U64;

А затем алгоритм k initделается так:

    static const SHA_U64 k[80] =  
    { 
        {0xD728AE22, 0x428A2F98}, {0x23EF65CD, 0x71374491}, ...
        ...
        ...
    }

Но мне нужно, чтобы логическое значение k [0] .high было одинаковым на любой машине.Таким образом, в этом примере мне понадобится другой массив k с заменой верхнего и нижнего значений.

После сохранения данных в рабочих параметрах любое побитовое манипулирование будет иметь одинаковый результат на обеих машинах с большим и меньшим порядком байтов.

Хороший метод - избегать приведения: импортируйте байты из входного буфера в ваши рабочие параметры с помощью макроса.Работайте с логическими значениями, не думая об отображении памяти.Экспортируйте выходные данные, чтобы переварить результат с помощью макроса.

Макрос для получения 32 битов из байтового буфера в int32 (BE = big endian):

    #define GET_BE_BYTES_FROM32(a) 
    ((((NQ_UINT32) (a)[0]) << 24) | 
    (((NQ_UINT32) (a)[1]) << 16)  | 
    (((NQ_UINT32) (a)[2]) << 8)   | 
    ((NQ_UINT32) (a)[3])) 

    #define GET_LE_BYTES_FROM32(a) 
    ((((NQ_UINT32) (a)[3]) << 24) | 
    (((NQ_UINT32) (a)[2]) << 16)  | 
    (((NQ_UINT32) (a)[1]) << 8)   | 
    ((NQ_UINT32) (a)[0])) 
1 голос
/ 09 июля 2011

Сама реализация SHA-256 должна позаботиться о заполнении - вам не придется сталкиваться с этим, если вы не реализуете свой собственный специализированный код SHA-256. Если да, обратите внимание, что правила заполнения, указанные в «шаге предварительной обработки», говорят, что длина - это 64-разрядное целое число с прямым порядком байтов. См. SHA-2 - Википедия

Трудно даже понять, что означало бы "не зависящее от порядка байтов", но порядок всех битов, байтов и слов для алгоритма хеширования имеет большое значение, поэтому я уверен, что не буду использовать этот термин. *

...