Вчера я спросил Являются ли GUID, сгенерированные в Windows 2003 безопасными для использования в качестве идентификаторов сеансов?, и ответ в сочетании с этой статьей GUID глобально уникальны, но подстроки GUID не меняют, поэтому я подумал о замене моего текущего механизма использования GUID как идентификатора сеанса в файлах cookie.
Поскольку для этого было немного работы, я решил запустить быстрый тест GUID на своем ПК с Vista, чтобы узнать, была ли последовательность идентификаторов GUID явно детерминированной (что меня беспокоит, если злоумышленник смог получить последовательность GUID, сгенерированных моим сервером, они могли бы генерировать новые сопоставимые).
В статье Раймонда Чена (которая ссылается на эту очень старую спецификацию UUID и GUID от 1998 года), GUID состоит из:
- 60 бит метки времени,
- 48 бит идентификатора компьютера,
- 14 бит уникального идентификатора и
- фиксируются шесть бит
Исходя из этого, если я генерирую 10 GUID, первые 15 символов ASCII (исключая "-" ) являются меткой времени, следующие 12 символов ASCII являются идентификатором компьютера, следующие 3,5 символа ASCII являются случайными, а последние 1,5 символа фиксированы.
Получение 10 GUID на моем ПК с Vista с помощью .Net System.Guid.NewGuid() дает:
b4e95ead-3619-4dc2-9102-cf7ab0efd927
a45ee719-decd-46b2-8355-7becbe406f74
9af68d75-35a0-4907-b6ab-f15e33acfe96
bed88fa3-3209-4a19-97dd-85d5428ea5f4
123cb39b-8d81-41c6-8894-f1257a8f7606
e2b1f6b1-5791-4a18-80a9-5dc668574ecb
c52aa660-2629-4659-bb83-5583081e5a1c
76eda32d-ceda-412e-8ade-30c47416e954
cbc4d45e-7281-40d2-9f90-00539b04fe98
be36524c-267c-4791-bc9e-3c20b29d7615
Единственный заметный паттерн из быстрого визуального контроля - это то, что 13-й символ ASCII всегда равен 4.
Мне снова не интересно, полагается ли полагаться на System.Guid для генерации псевдослучайных идентификаторов сеансов, чтобы защитить веб-приложение, где взлом идентификатора сеанса будет стоить не более тысячи долларов?
Обновление. Вместо использования GUID теперь я планирую сгенерировать свой идентификатор сеанса, используя подход ниже. Я преобразовываю 384-битное случайное число в строку с байтом 0x00, чтобы оно было подходящим для использования в файле cookie HTTP.
RNGCryptoServiceProvider rngProvider = new RNGCryptoServiceProvider();
byte[] myKey = new byte[48];
rngProvider.GetBytes(myKey);
string sessionID = null;
myKey.ToList().ForEach(b => sessionID += b.ToString("x2"));
Console.WriteLine(sessionID);