Реализация SQL CHECKSUM в Java - PullRequest
       20

Реализация SQL CHECKSUM в Java

4 голосов
/ 01 августа 2011

У меня есть база данных в SQL Server 2008, которая выполняет аутентификацию пользователя с помощью хранимой процедуры для существующего веб-приложения PHP. Веб-приложение отправляет хранимой процедуре строку, однако хранимая процедура сохраняет ее, и проверяет значение с помощью контрольной суммы SQL (http://msdn.microsoft.com/en-us/library/ms189788.aspx).. Хранимая процедура преобразует строку как NVARCHAR (50) и сохраняет CHECKSUM как int в таблица пользователей.

Сейчас я пишу новое Java-приложение поверх существующей базы данных и пишу собственный менеджер аутентификации Spring. Я хотел бы повторно реализовать алгоритм CHECKSUM в Java, поэтому мне не нужно вызывать хранимую процедуру для выполнения преобразования, однако я не могу найти никакой документации о том, как работает SQL CHECKSUM.

Я попробовал следующий код, предположив, что это CRC32, однако он не может вернуть то же значение, что и SQL CHECKSUM:

String pass = "foobar";
CRC32 crc32 = new CRC32();
crc32.update(pass.getBytes("UTF-16")); //This is due to the stored procedure casting as nvarchar
crc32.getValue();

Может кто-нибудь указать мне на алгоритм, который использует SQL CHECKSUM, чтобы я мог повторно реализовать его в Java?

Вопрос также не в том, какой алгоритм обеспечивает лучший хэш для безопасности. Безопасность в данном конкретном случае выходит за рамки требований, поскольку мы не готовы к принудительному сбросу пароля для всей системы. Вопрос в том, какой алгоритм используется T-SQL CHECKSUM, чтобы его можно было повторно реализовать. Этот конкретный вариант использования предназначен для аутентификации, однако существует вероятность того, что это необходимо во многих различных приложениях.

Ответы [ 2 ]

3 голосов
/ 18 сентября 2013

На форуме SQL Server на этой странице указано:

Встроенная функция CHECKUM в SQL Server основана на последовательности 4-битных операций левого вращения xor. См. сообщение для более подробного объяснения.

Мне удалось перенести BINARY_CHECKSUM на c # (извините, у меня под рукой нет компилятора Java), и, похоже, он работает ... Я посмотрю на простой CHECKSUM позже ...

private int SQLBinaryChecksum(string text)
{
    long sum = 0;
    byte overflow;
    for (int i = 0; i < text.Length; i++)
    {
        sum = (long)((16 * sum) ^ Convert.ToUInt32(text[i]));
        overflow = (byte)(sum / 4294967296);
        sum = sum - overflow * 4294967296;
        sum = sum ^ overflow;
    }

    if (sum > 2147483647)
        sum = sum - 4294967296;
    else if (sum >= 32768 && sum <= 65535)
        sum = sum - 65536;
    else if (sum >= 128 && sum <= 255)
        sum = sum - 256;

    return (int)sum;
}
0 голосов
/ 01 августа 2011

Я бы предложил вам заменить TSQL CHECKSUM на HASBYTES алгоритмом MD5, чтобы вы легко могли найти реализацию MD5 в Java.

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

Посмотрите, как использовать хеш-коды с MD5:

HASHBYTES('MD5', @input)

РЕДАКТИРОВАТЬ: Ответ на комментарии относительно MD5

HASHBYTES также поддерживает алгоритмы SHA и SHA1, так что никаких проблем, если вы не будете использовать MD5

...