Имам метод в клас, който дешифрира променлива и я връща. Премахвам върнатата променлива с "del" след употреба.
Каква е опасността от достъп до тези стойности за боклук... и как най-добре мога да се защитя от тях?
Ето кода:
import decrypter
import gc
# mangled variable names used
def decrypt(__var):
__cleartext = decrypter.removeencryption(__var)
return __cleartext
__p_var = "<512 encrypted password text>"
__p_cleartext = decrypt(__p_var)
<....do login with __p_cleartext...>
del __p_var, __p_cleartext
gc.collect()
Може ли някоя от променливите, включително __var и __cleartext да се използва на този етап?
Благодаря!
Гугълнах още малко. Преди да прекарам няколко часа в грешен път... това, което чувам е:
- Съхранявайте паролата като осолен хеш в системата (което се прави в момента).
- Солта за хеша трябва да бъде въведена от потребителя при стартиране на пакета (в момента се прави)
- Солта обаче трябва да се държи в C процес, а не в python.
- Скриптът на Python трябва да предаде хеша на C процеса за дешифриране.
Скриптът на python обработва влизането за mysql база данни и паролата е необходима за отваряне на DB връзката.
Ако кодът беше в съответствие с...
# MySQLdb.connect(host, user, password, database)
mysql_host = 'localhost'
mysql_db = 'myFunDatabase'
hashed_user = '\xghjd\xhjiw\xhjiw\x783\xjkgd6\xcdw8'
hashed_password = 'ghjkde\xhu78\x8y9tyk\x89g\x5de56x\xhyu8'
db = MySQLdb.connect(mysql_host, <call_c(hashed_user)>, <call_c(hashed_password)>, mysql_db])
Това би ли разрешило (поне) проблема с питона, който оставя боклук навсякъде?
P.s. Намерих и публикацията за memset (Маркиране на данни като чувствителни в python), но предполагам, че ако използвам C за дешифриране на хеша, това не е полезно.
P.P.S. Dycrypter в момента е скрипт на Python. Ако трябваше да добавя memset към скрипта и след това да го „компилирам“ с помощта на py2exe или pyinstaller... това всъщност ще направи ли нещо, за да защити паролата? Инстинктът ми казва не, тъй като всичко, което pyinstaller прави, е да пакетира нормалния интерпретатор и същия байткод, който създава локалният интерпретатор... но не знам достатъчно за него...?
И така...следвайки предложението на Aya за създаване на модула за криптиране на C, колко забележим отпечатък от паметта ще остави следната настройка. Част от големия проблем е; способността за дешифриране на паролата трябва да остане налична по време на изпълнението на програмата, тъй като тя ще бъде извиквана многократно...това не е еднократно нещо.
Направете C обект, който се стартира, когато потребителят влезе. Той съдържа рутинната декриптираща програма и съхранява копие на солта, въведена от потребителя при влизане. Съхранената сол е скрита в работещия обект (в паметта), тъй като е била хеширана от неговата собствена рутина за криптиране с помощта на произволно генерирана сол.
Произволно генерираната сол все още трябва да се съхранява в променлива в обекта. Това всъщност не е за осигуряване на солта, а просто за да се опитаме да скрием отпечатъка на паметта, ако някой надникне в него (което прави солта трудна за идентифициране). т.е. c-obj
mlock() /*to keep the code memory resident (no swap)*/
char encrypt(data, salt){
(...)
return encrypted_data
}
char decrypt(data, salt){
(...)
return decrypted_data
}
stream_callback(stream_data){
return decrypt(stream_data, decrypt(s-gdhen, jhgtdyuwj))
}
void main{
char jhgtdyuwj=rand();
s-gdhen = encrypt(<raw_user_input>, jhgtdyuwj);
}
След това скриптът на python извиква директно C обекта, който предава некриптирания резултат направо в извикването на MySQLdb, без да съхранява никакви връщания в която и да е променлива. т.е.
#!/usr/bin/python
encrypted_username = 'feh9876\xhu378\x&457(oy\x'
encrypted_password = 'dee\x\xhuie\xhjfirihy\x^\xhjfkekl'
# MySQLdb.connect(host, username, password, database)
db = MySQLdb.connect(self.mysql_host,
c-obj.stream_callabck(encrypted_username),
c-obj.stream_callback(encrypted_password),
self.mysql_database)
Какъв отпечатък в паметта може да остави това, което може да бъде подслушвано?