Внедряване на CRAM-MD5

Разглеждам прилагането на CRAM-MD5 удостоверяване за IMAP и SMTP сървър. Проблемът е, че CRAM изглежда изисква парола с ясен текст, за да бъде достъпна по всяко време. Сървърът изпраща на клиента уникално предизвикателство и клиентът връща:

MD5( MD5(password, challenge), MD5( password ) )

Не виждам начин да проверя това без парола с ясен текст, спецификацията не казва, че трябва да има налична такава, но изглежда логично.

Единственото решение, което мога да измисля, е да криптирам (правилно криптирам, не хеширам) паролата в базата данни (вероятно използвайки базиран на RSA ключ AES, тъй като вече имам какво да се справя с това) и да я декриптирам, когато трябва да сравня, изглежда много бавен начин, тъй като ще има нужда от дешифриране и хеширане за всяко едно влизане в SMTP и IMAP.

Това ли е най-доброто решение/най-ефективното решение?

Или, по-добре, сега CRAM е остарял, защото дори по-малко сигурното удостоверяване по кабела сега е защитено с SSL?


person Paystey    schedule 20.07.2011    source източник


Отговори (3)


номерът е, че всичко, от което наистина се нуждаете, е нефинализираният md5 на паролата, който е същият като междинното състояние на контекста md5 преди финализирането.

MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, password, length);

ако направите това и след това съхраните стойността на ctx като hashed, тогава можете да използвате нейни копия в CRAM MD5 по този начин

за MD5(password, challenge)

MD5Update(&hashed, challenge, length);
MD5Final(&digest, &hashed);

и за MD5( password )

MD5Final(&digest, &hashed);

останалата част от MD5( MD5(password, challenge), MD5( password ) ) е доста проста

бих искал да използвам python за този пример, но в стандартния md5 няма начин да получа достъп до състоянието на md5 обект, така че използвах api на libmd5

person Dan D.    schedule 23.07.2011
comment
Иска ми се да го бяхте написали на python, това е, на което пиша това :p. Това изглежда е най-доброто решение. Поддържа паролата донякъде сигурна (доколкото MD5 може да бъде). Така че може да използвам идеята си да го криптирам така или иначе и след това пак да мога да предоставя функционалност на CRAM MD5. - person Paystey; 24.07.2011
comment
Това може да е по-добре от съхраняването на паролата в обикновен текст, тъй като потребителите, които използват една и съща парола на няколко места, може да бъдат по-малко засегнати, но базата данни все пак съдържа всичко, от което се нуждаете за влизане. Което е трудно да се избегне за CRAM. - person Christopher Creutzig; 28.07.2011

Понастоящем има чернова на RFC, която предлага преместване на DIGEST-MD5 към исторически статус, CRAM MD5 също не е в много по-добро състояние.

Ако искате подходяща сигурност, започнете с TLS и SASL - в този режим PLAIN се счита за приемлив, но ако, доколкото сте загрижени, не е задоволителен, тогава бих препоръчал внедряването на GSSAPI или NTLM върху него.

person Olipro    schedule 23.07.2011
comment
Благодаря, състоянието на RFC помага много за разбирането ми. Тези дни се борех да видя смисъла на CRAM MD5, тъй като TLS с по-прост протокол изглеждаше много по-добре. Искам обаче да не добавям друг слой между базата данни и програмата, защото изобщо не е предназначен да бъде абстрахиран, така че GSSAPI или NTLM не са наистина опции. - person Paystey; 23.07.2011
comment
Надявам се, че планирате да напишете и свой собствен имейл клиент тогава ;) - person Olipro; 23.07.2011
comment
Защо така? Предоставят ли GSSAPI и NTLM удостоверяване на клиента? От краткия преглед разбрах, че това са механизми за удостоверяване от страна на сървъра. - person Paystey; 24.07.2011
comment
Единствените протоколи, за които знам, че се поддържат от съвместими с RFC имейл клиенти, са CRAM, DIGEST, NTLM, GSSAPI, PLAIN и Login. - person Olipro; 24.07.2011
comment
Ще разгледам някои цифри за използването на NTLM и GSSAPI, за да видя дали да ги внедря, тъй като честно казано никога не съм чувал за тях. Благодаря за подкрепата. - person Paystey; 24.07.2011

Източниците за Python на hashlib.py кажете, че можете да инициализирате екземпляр на хеш с двоични данни, но от употребата изглежда означава "инициализиране с хеша на тези данни".

Можете обаче да клонирате обекта с непокътнато вътрешно състояние, така че да можете да отделите обекта и да го съхраните вместо паролата. За да получите паролата MD5, махнете обекта, а за да получите хеша на предизвикателството, махнете го и извикайте метода му update() с данните за предизвикателството.

person Adrian    schedule 28.07.2011
comment
Но това може ли да бъде откъснато от всеки и да се използва със сигурност? Ако кодът има достъп до състоянието на чист текст, за да може да актуализира хеша, тогава със сигурност той все още може да бъде намерен. Оценявам, че това все още е доста добро от гледна точка на обфускацията, защото ще отнеме малко усилия, за да разберем какво е и как да го отменим. Но мисля, че ще го шифровам напълно в DB. - person Paystey; 28.07.2011
comment
Без да проверявам източника, бих предположил, че обектът запазва само текущия хеш, тъй като не е необходимо да запазвате обикновения текст - което би било векторът за инициализация, който бихте искали, както е посочено в приетия отговор по-горе. - person Adrian; 22.08.2011