Кащеева смерть — защищаем свои пароли с помощью аппаратного хранилища ключей Android
Несколько лет назад меня начала посещать мысль, что менеджеры паролей всё-таки «для честных людей». Как раз все встречные и поперечные стали заявлять, что у них теперь сквозное шифрование… И настали типа спокойные и безопасные времена (ну если не считать миллиардов, которые крадут с криптобирж каждый второй день, прослушки всех этих чатов со сквозным шифрованием, слива баз паролей, взлома LastPass…)
Короче, решил я замутить что-то своё, чтоб не хранить все свои доступы удобно (не)доступными в одном файле KeePass, а то ведь мало ли что. Просто так, из принципа. Биткойнов не держу.
Первоначальная мысль смастерить какую-нибудь «машинку», которая будет хранить пароли, как-то не складывалась и упиралась в вопрос корявого интерфейса этой самой «машинки». Да и что потом делать с этим паролем? Печатать на клавиатуре, глядя на экран? Подключить по USB? Так ничего и не придумал.
Зато выяснил для себя, что Android OS имеет достаточно интересное аппаратное хранилище ключей.
- зашифрованный асимметричным ключом пароль;
- передаётся на телефон;
- тот его расшифровывает;
- вводим пароль на компе.
Небольшая проблема: кроме (3) ничего не понятно. Какой ключ… как передавать и получать данные… по сети не хотелось – не всегда телефон в той же локальной сети, что и комп.
Как оказалось, Android может косить под Bluetooth клавиатуру. Штуковина называется BluetoothHidDevice.
Вопрос (4) решён! В теории… Практика написания виртуальной клавиатуры оказалась куда сложнее, потому как BluetoothHidDevice просто говорит «я устройство ввода-вывода» (и на том спасибо!), а вот протокол клавиатуры пришлось писать самому. Так тяжело мне еще ничего не давалось.
По проблеме (2): или пароли лежат где-то в облаке в зашифрованном виде (что, в общем, тоже ОК, если у каждого пароля свой сильный ключ), или… а давай прикрутим фонтанные коды, чтоб можно было читать их с любого монитора!
Эти же фонтанные коды решили и проблему с сохранностью ключа. Если Android импортирует ключ, то сам ключ он вам больше не отдаст. В этом и есть вся прелесть. Но вот незадача: пропал телефон – а с ним и ключ шифрования. GAME OVER…
Пришлось генерировать документ с QR кодами, в которых содержится этот самый ключ. И защитить его AES с транспортным паролем подлиннее, чтоб не попал, к кому не надо. Можно распечатать, положить в сейф, у кого есть. Ну или в огороде зарыть.
Осталось только прикрутить камеру к Android приложению. Хорошо, что есть CameraX, а то бы до сих пор сидел…
Эпилог
Имеем app на телефоне, выполняющее функцию хранилища ключей. Плюс всякий плюшки типа генератора паролей и виртуальной Bluetooth клавиатуры. И java программку на компе, которая превращает данные в QR коды и выполняет шифрование открытым ключом.
Где сами пароли после этого хранить? Да хоть где. Каждый пароль в своем «конверте», который зашифрован уникальным ключом AES. Сам ключ AES в том же конверте лежит, да только он зашифрован ключом RSA (то есть, шифровать данные можно где угодно и без доступа к телефону). А закрытый ключ RSA в аппаратном хранилище Android лежит, и без биометрии до него не добраться. Да и для расшифровки конверт с паролем сначала должен попасть на телефон.
А вот и сам конверт. Получилось на первый взгляд немного длинновато – но нам же это не печатать.
oms00_AAEAAAAg21N0EVMYnl7uMSeQGZwFfGf43ysMvANVTWWN7OJ/pzkAAAAQ87NChX7bQv1P35zZlTBICAEABmwOQYvROKWcWUI32CtAttm9m7EmghJRERlcnjOc8PhArnkGtGYq9M2sS0ZSNnsZuH7w6hD/LcAEUnWRQ34ynGy/jsiv4B4iwA3y0i6cFBmrh2jJEpZxL3gNPRGNfcep6eey22RUNE+CJflf91ttUTJKW3FyKTB9Yed7hqSy5xeYbFuL1h6mWLo3ZHtth+A0HGZXG0V18uwdr/fv7QkmXLT65KOzlv8a5+vjnTKF/S8u9IjC8/D9XixbScB9NuaCFK2Qq0eJ1Hu9bVEFYaGhdgWqhRB/9y6g776ghRkRzXlu8Z/oExVZ9aN5DUg4awGzs0YamMBKP6fkYFXHuyBE6QAgYc2BkuxKjYyNM9EHcai+tE27uS3qKRYoRW1/xpbOPdg=
App пока тестирую в закрытом режиме, кому интересно – пишите.
Бонус
Тем же способом, имея открытый ключ пользователя (можно экспортировать из телефона), можно совсем отказаться от паролей на своём сайте. Генерируешь одноразовый пароль, шифруешь ключом пользователя, показываешь QR код, сравниваешь.