Objective C SHA512 хэш двух NSData

#objective-c #nsdata #sha512

#objective-c #nsdata #sha512

Вопрос:

Вот Java-код, который вычисляет SHA512 хэш массива байтов с использованием соли:

 private static String DIGEST_ALGORITHM = "SHA-512";

    public static byte[] getHash(final byte[] data, final byte[] salt) throws NoSuchAlgorithmException
{
    final MessageDigest md = MessageDigest.getInstance(DIGEST_ALGORITHM);
    md.reset();
    if (salt != null)
    {
        md.update(salt);
    }
    return md.digest(data);
  

В Objective C я использую этот алгоритм для вычисления хэша NSData:

 @implementation NSData (CommonDigest)

- (NSData *) SHA512Hash {
unsigned char hash[CC_SHA512_DIGEST_LENGTH];
(void) CC_SHA512( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA512_DIGEST_LENGTH] );
}
  

Это работает отлично, вычисляет тот же хэш, что и Java-код, если я использую те же единичные данные (т. Е. Соль равна нулю в Java-коде). Проблема в том, что, если я хочу вычислить хэш двух NSData, т. Е. есть соль (второй параметр в коде Java не равен нулю). Вы можете видеть, что в коде Java, если значение salt не равно null, выполняется обновление, а затем вызывается метод digest. Где-то я читал, что эта операция равна объединению двухбайтового массива (массивов данных и соли с System.arraycopy) и вызову дайджест для результирующего массива.
Однако, если я сделаю это в Objective C (с помощью метода NSMutableData appendData), я не получу тот же результат. Как я могу это исправить?
Я вижу в классе CommonDigest похожие методы, но я не знаю, как я могу их использовать…Я думаю об этих методах:

 extern int CC_SHA512_Init(CC_SHA512_CTX *c);
extern int CC_SHA512_Update(CC_SHA512_CTX *c, const void *data, CC_LONG len);
extern int CC_SHA512_Final(unsigned char *md, CC_SHA512_CTX *c);
extern unsigned char *CC_SHA512(const void *data, CC_LONG len, unsigned char *md);
  

Итак, я хотел бы создать метод, подобный этому:

 @implementation NSData (CommonDigest)

- (NSData *)SHA512HashWithSalt:(NSData *)salt {...}
  

Комментарии:

1. Не могли бы вы вставить код, который вы использовали для добавления данных в NSMutableData ? Из вашего Java-кода похоже, что фактические данные добавлены к соли.

Ответ №1:

Я не запускал этот код и не сравнивал его с реализацией Java, но он должен работать:

 @implementation NSData (CommonDigest)

- (NSData *)SHA512HashWithSalt:(NSData *)salt {
    unsigned char hash[CC_SHA512_DIGEST_LENGTH];
    CC_SHA512_CTX context;
    CC_SHA512_Init(amp;context);
    if ([salt length]) {
        CC_SHA512_Update(amp;context, [salt bytes], (CC_LONG)[salt length]);
    }
    CC_SHA512_Update(amp;context, [self bytes], (CC_LONG)[self length]);
    CC_SHA512_Final(hash, amp;context);
    return [NSData dataWithBytes:hash length:CC_SHA512_DIGEST_LENGTH];
}

@end
  

Комментарии:

1. Вот метод, который я использовал ранее: (NSData *)getHashOfData:(NSData *)sourceData withSalt:(NSData *)salt { NSData *хэш = ноль; NSMutableData *слияние = [NSMutableData dataWithData:SourceData]; if (соль != ноль) { [объединить appendData: соль]; } хэш = [объединить SHA512Hash]; вернуть хэш; } `

2. @user703598 Итак, вы добавляете соль к своим данным, когда на самом деле кажется, что ваш Java-код добавляет ее.

3. Значит, я должен добавлять данные к соли, а не соль к данным?

4. @user703598 Это то, что делает ваш Java-код. Обратите внимание, что он вызывает md.update(salt) перед вызовом md.digest(data) : сначала соль, затем данные.

5. Да, вы правы, предложенный вами способ (обратный порядку добавления) и написанный вами код дают тот же результат. Но результат не совпадает с результатом кода Java. Я думаю, что ошибка где-то в другом месте…