У меня есть метод в классе, который расшифровывает переменную и возвращает ее. Я удаляю возвращаемую переменную с помощью «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, и пароль необходим для открытия соединения с БД.
Если бы код был похож на...
# 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 для расшифровки хэша, это бесполезно.
П.П.С. В настоящее время dycrypter представляет собой скрипт Python. Если бы я добавил memset в скрипт, а затем «скомпилировал» его с помощью py2exe или pyinstaller… помогло бы это защитить пароль? Мои инстинкты говорят нет, так как все, что делает pyinstaller, это упаковывает обычный интерпретатор и тот же байт-код, который создает локальный интерпретатор... но я недостаточно знаю об этом...?
Итак... следуя предложению Аи сделать модуль шифрования на 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)
Какой след в памяти это может оставить, который можно было бы отследить?