Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » PyQt4 | Программа для хранения учётных записей, паролей [RSS Feed]

#1 Март 14, 2017 10:53:20

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQt4 | Программа для хранения учётных записей, паролей

# Python 3. PyQt4
Пишу программу для хранения учётных записей.
Пока что модель программы выглядит вот так:

Накручивать функционал я буду потом. Сейчас главное отработать общую механику.
Хочу обратить внимание на то, что две левые “колонки” - это QListWidget. Поле с паролем буду менять на поле со звёздочками. База данных записана в виде списка с тройной вложенностью.
Сейчас база загружается с файла “basa.py”, а сохраняется в “basa3.pkl” - такая схема чисто для отработки механики.
В дальнейшем собираюсь шифровать базу данных и использовать мастер-пароль. Однако пока не разбирался с этим (уже предчувствую, как мне будут писать, что я изначально неправильно сохраняю базу данных…).

В общем, если кому интересно, то можете принять участие в разработке.

На данный момент у меня есть вопрос о поведении QListWidget.
Суть проблемы. Выбираю категорию, в листе учёток появляется список учёток. Выбираю учётку, в полях карточки учётной записи появляются данные. Если я меняю учётную запись, то данные в карточке меняются. Всё хорошо. Однако, если поменять категорию, то индекс учётки не сбрасывается (пытаюсь понять, как его всё-таки сбросить), поэтому карточка начинает лагать: в свои поля она начинает вставлять список учёток.

Код программы:

 # Python 3. PyQt4
# -*- coding: utf-8 -*-
import sys
import pickle
import res.basa as basa
from PyQt4 import QtGui, QtCore
'''F_R = open('res/basa3.pkl', 'rb')
db = pickle.load(F_R)'''
db = basa.db
db_кат = basa.db[0]
кат_index = 0
уч_index = 0
# ГРАФИКА
class Window(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        
        self.setMinimumSize(450, 400) # Миниамльная ширина и высота окна
        self.resize(600, 400) # шир / выс окна, работает парал. с setMinimumSize
        self.setWindowTitle('Хранение учётных записей') # Заголовок
        self.setWindowIcon(QtGui.QIcon('res\icon.png')) # Иконка 
        
        # БЛОК СОЗДАНИЯ FRAME
        self.frame_1 = QtGui.QFrame()
        self.frame_1.setFrameShape(1)
        self.frame_1_lay = QtGui.QGridLayout(self.frame_1)
        
        # БЛОК СОЗДАНИЯ LABEL
        self.lbl_кат = QtGui.QLabel('Категории:')        
        self.lbl_уч = QtGui.QLabel('Учётки:')
        self.lbl = QtGui.QLabel()
        self.lbl_адрес = QtGui.QLabel('Адрес:')
        self.lbl_логин = QtGui.QLabel('Логин:')
        self.lbl_пароль = QtGui.QLabel('Пароль:')
        self.lbl_почта = QtGui.QLabel('Почта:')
        self.lbl_имя = QtGui.QLabel('Имя:')
        self.lbl_фмл = QtGui.QLabel('Фамилия:')
        self.lbl_дата_откр = QtGui.QLabel('Открыто:')
        self.lbl_дата_закр = QtGui.QLabel('Закрыто:')
      
        # БЛОК СОЗДАНИЯ ПОЛЕЙ
        self.pole_кат = QtGui.QLineEdit()
        self.pole_кат.setPlaceholderText('Добавить категорию')
        
        self.pole_уч = QtGui.QLineEdit()
        self.pole_уч.setPlaceholderText('Добавить учётку')
        
        self.pole_адрес = QtGui.QLineEdit()
        self.pole_адрес.textChanged.connect(self.on_st_0)
        
        self.pole_логин = QtGui.QLineEdit()
        self.pole_логин.textChanged.connect(self.on_st_1)
        
        self.pole_пароль = QtGui.QLineEdit()
        self.pole_пароль.textChanged.connect(self.on_st_2)
        
        self.pole_почта = QtGui.QLineEdit()
        self.pole_почта.textChanged.connect(self.on_st_3)
        
        self.pole_имя = QtGui.QLineEdit()
        self.pole_имя.textChanged.connect(self.on_st_4)
        
        self.pole_фмл = QtGui.QLineEdit()
        self.pole_фмл.textChanged.connect(self.on_st_5)
        
        self.pole_дата_откр = QtGui.QLineEdit()
        self.pole_дата_откр.textChanged.connect(self.on_st_6)
        
        self.pole_дата_закр = QtGui.QLineEdit()
        self.pole_дата_закр.textChanged.connect(self.on_st_7)
        # БЛОК СОЗДАНИЯ КНОПОК        
        self.button_prnt = QtGui.QPushButton('Print db')
        self.button_prnt.clicked.connect(self.on_prnt)
        
        self.button_кат_плюс = QtGui.QPushButton('+')
        self.button_кат_плюс.clicked.connect(self.on_kat_plus)
        
        self.button_кат_минус = QtGui.QPushButton('-')        
        self.button_кат_минус.clicked.connect(self.on_kat_minus)
        
        self.button_уч_плюс = QtGui.QPushButton('+')
        self.button_уч_плюс.clicked.connect(self.on_uch_plus)
        
        self.button_уч_минус = QtGui.QPushButton('-')
        self.button_уч_минус.clicked.connect(self.on_uch_minus)
        
        self.button_copy = QtGui.QPushButton('Копировать')
        self.button_плюс = QtGui.QPushButton('+')
        self.button_минус = QtGui.QPushButton('-')
        
        self.button_адрес = QtGui.QPushButton('Адрес')
        self.button_логин = QtGui.QPushButton('Логин')
        self.button_пароль = QtGui.QPushButton('Пароль')
        self.button_почта = QtGui.QPushButton('Почта')        
        
        # Q_LIST_WIDGET
        self.listWidget_кат = QtGui.QListWidget()        
        self.listWidget_кат.addItems(db_кат)
        self.listWidget_кат.setFixedWidth(150)
        
        self.listWidget_кат.currentRowChanged.connect(self.on_kat) # изм номера строки категории
        self.listWidget_кат.currentRowChanged.connect(self.on_st_clear)
        # self.listWidget_кат.currentRowChanged.connect(self.on_kat_crnt) # очистка строк учётки
        self.listWidget_кат.itemDoubleClicked.connect(self.on_kat_edit) # редактирование имени категории
        
        self.listWidget_уч = QtGui.QListWidget()
        self.listWidget_уч.setFixedWidth(150)
        self.listWidget_уч.currentRowChanged.connect(self.on_uch)
        # БЛОК РАЗМЕТКИ       
        self.grid_os = QtGui.QGridLayout() # создание сетки
        self.grid_os.setSpacing(5)
        self.grid_os.addWidget(self.lbl_кат, 1,0,1,2)
        self.grid_os.addWidget(self.lbl_уч, 1,2,1,2)
        self.grid_os.addWidget(self.button_copy, 1, 4)
        
        self.grid_os.addWidget(self.listWidget_кат, 2,0,1,2)
        self.grid_os.addWidget(self.listWidget_уч, 2,2,1,2)
        
        self.grid = QtGui.QGridLayout() # создание сетки
        self.grid.addWidget(self.frame_1,0,0) # Фрейм 1
        self.frame_1_lay.addWidget(self.button_адрес,1,0)
        self.frame_1_lay.addWidget(self.button_логин,2,0)
        self.frame_1_lay.addWidget(self.button_пароль,3,0)
        self.frame_1_lay.addWidget(self.button_почта,4,0)
        # self.frame_1_lay.addWidget(self.lbl_адрес,1,0,1,3)
        # self.frame_1_lay.addWidget(self.lbl_логин,2,0,1,3)
        # self.frame_1_lay.addWidget(self.lbl_пароль,3,0,1,3)
        # self.frame_1_lay.addWidget(self.lbl_почта,4,0,1,3)
        self.frame_1_lay.addWidget(self.lbl_имя,5,0,1,3)
        self.frame_1_lay.addWidget(self.lbl_фмл,6,0,1,3)
        self.frame_1_lay.addWidget(self.lbl_дата_откр,7,0,1,3)
        self.frame_1_lay.addWidget(self.lbl_дата_закр,8,0,1,3)
        
        self.frame_1_lay.addWidget(self.pole_адрес,1,3,1,3)
        self.frame_1_lay.addWidget(self.pole_логин,2,3,1,3)
        self.frame_1_lay.addWidget(self.pole_пароль,3,3,1,3)
        self.frame_1_lay.addWidget(self.pole_почта,4,3,1,3)
        self.frame_1_lay.addWidget(self.pole_имя,5,3,1,3)
        self.frame_1_lay.addWidget(self.pole_фмл,6,3,1,3)
        self.frame_1_lay.addWidget(self.pole_дата_откр,7,3,1,3)
        self.frame_1_lay.addWidget(self.pole_дата_закр,8,3,1,3)
        
        self.grid_os.addWidget(self.pole_кат, 3,0,1,2)
        self.grid_os.addWidget(self.pole_уч, 3,2,1,2)
        
        self.grid_os.addWidget(self.button_кат_плюс, 4,0)
        self.grid_os.addWidget(self.button_кат_минус, 4,1)
        self.grid_os.addWidget(self.button_уч_плюс, 4,2)
        self.grid_os.addWidget(self.button_уч_минус, 4,3)
        
        self.grid_os.addWidget(self.button_prnt, 4, 6)
               
        self.grid_os.addLayout(self.grid,2,4,1,6)
        self.setLayout(self.grid_os) # установка рабочей области
    def basa_save(self): # сохранить базу данных
        F_W = open('res/basa3.pkl', 'wb')
        pickle.dump(db,F_W)
        F_W.close()
            
    def on_kat(self): # изм категории
        кат_index = self.listWidget_кат.currentRow() # принимает номер строки
        уч_index = None        
        print('кат_index = ',кат_index)
        уч_lst = db[кат_index+1][0]
        # print('уч_lst = ',уч_lst)
        self.listWidget_уч.clear()
        self.listWidget_уч.addItems(уч_lst)
        # print('db = ',db)        
        return кат_index
    
    def on_uch(self): # изм учётки
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow() # принимает номер строки 
        if уч_index == None:
            уч_index = None
        else:
            уч_index = self.listWidget_уч.currentRow()
            self.pole_адрес.setText(db[кат_index+1][уч_index+1][0])
            self.pole_логин.setText(db[кат_index+1][уч_index+1][1])       
            self.pole_пароль.setText(db[кат_index+1][уч_index+1][2])
            self.pole_почта.setText(db[кат_index+1][уч_index+1][3])
            self.pole_имя.setText(db[кат_index+1][уч_index+1][4])
            self.pole_фмл.setText(db[кат_index+1][уч_index+1][5])
            self.pole_дата_откр.setText(db[кат_index+1][уч_index+1][6])
            self.pole_дата_закр.setText(db[кат_index+1][уч_index+1][7])
        print('кат_index = ',кат_index)
        print('уч_index = ',уч_index)
    
    def on_kat_plus(self): # добавить категорию
        кат_index = self.listWidget_кат.currentRow()
        a = self.pole_кат.text() # имя категории
        if a:
            self.listWidget_кат.insertItem(кат_index+1, a)
        db_кат.insert(кат_index+1, a) # к списку категорий      
        db.insert(кат_index+2, [[]]) # пустой список учёток
        Window().basa_save()        
        self.pole_кат.clear()
        print('db плюс = ',db)
    
    def on_kat_minus(self): # удалить категорию
        кат_index = self.listWidget_кат.currentRow()        
        self.listWidget_кат.takeItem(кат_index)
        del db[0][кат_index]
        del db[кат_index+1]
        Window().basa_save()        
        print('кат_index = ',кат_index)        
        print('db минус = ',db)
    
    def on_uch_plus(self): # добавить учётку
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        b = self.pole_уч.text() # имя учётки
        if b:
            self.listWidget_уч.addItem(b)
            self.listWidget_уч.sortItems()
        db[кат_index+1][0].append(b) # к списку учёток
        db[кат_index+1][0].sort()
        db[кат_index+1][1:].sort()
        db[кат_index+1].append(['','','','','','','',''])
        print('db плюс = ')
        Window().prnt(db)
        print('db[кат_index+1][уч_index+1][0] = ',db[кат_index+1][уч_index+1][0])
        self.pole_уч.clear()
        Window().basa_save()
    
    def on_uch_minus(self): # удалить учётку
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        self.listWidget_уч.takeItem(уч_index)
        del db[кат_index+1][0][уч_index]
        del db[кат_index+1][уч_index+1]        
        Window().prnt(db)
        Window().basa_save()
        print('db минус = ')
    def on_kat_crnt(self):
        1
    def on_kat_edit(self):
        кат_index = self.listWidget_кат.currentRow()
        self.listWidget_кат.editItem(0)
    # ЗАПОЛНЕНИЕ УЧЁТКИ
    def on_st_0(self):
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()               
        db[кат_index+1][уч_index+1][0] = self.pole_адрес.text()
        Window().basa_save()
    def on_st_1(self):
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        db[кат_index+1][уч_index+1][1] = self.pole_логин.text()
        Window().basa_save()
    def on_st_2(self):
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        db[кат_index+1][уч_index+1][2] = self.pole_пароль.text()
        Window().basa_save()
    def on_st_3(self):
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        db[кат_index+1][уч_index+1][3] = self.pole_почта.text()
        Window().basa_save()
    def on_st_4(self):
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        db[кат_index+1][уч_index+1][4] = self.pole_имя.text()
        Window().basa_save()
    def on_st_5(self):
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        db[кат_index+1][уч_index+1][5] = self.pole_фмл.text()
        Window().basa_save()
    def on_st_6(self):
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        db[кат_index+1][уч_index+1][6] = self.pole_дата_откр.text()
        Window().basa_save()
    def on_st_7(self):
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        db[кат_index+1][уч_index+1][7] = self.pole_дата_закр.text()        
        print('db хар = ')
        Window().basa_save()
    def on_st_clear(self): # очистка полей учётки
        '''self.pole_адрес.setText('')
        self.pole_логин.setText('')       
        self.pole_пароль.setText('')
        self.pole_почта.setText('')
        self.pole_имя.setText('')
        self.pole_фмл.setText('')
        self.pole_дата_откр.setText('')
        self.pole_дата_закр.setText('')'''
    def on_prnt(self, A):
        Window().prnt(db)
            
    def prnt(self, A):
        for i in A:
            print(i)
 
# КОНЕЦ
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

Файл базы данных basa.py
 db = [['АААА','ББББ'],
      [['А - учёт 0','А - учёт 1'],
       ['aaa0.ru','egir0','123456','egir@ex.ru','','','12.01.2017',''],
       ['aaa1.ru','egir1','123456','egir@ex.ru','','','12.01.2017','']],
      [['Б - учёт 0','Б - учёт 1'],
       ['bbb0.ru','fvr','123456','nch@ex.ru','','','15.08.2013',''],
       ['bbb1.ru','sadw','123456','gfhd@ex.ru','','','19.03.2016','']]]
Прикладываю архив с программой

Отредактировано Kyrym (Март 14, 2017 11:01:10)

Прикреплённый файлы:
attachment Архив_Хранение_учёток.zip (5,7 KБ)

Офлайн

#2 Март 14, 2017 14:00:17

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQt4 | Программа для хранения учётных записей, паролей

Это потому что если строка в КУвиджетЛисте не выбрана то currentRow() вернет -1 а не None
когда вы делаете listWidget.clear() текущий индекс сбрасываеться в -1 поскольку элемнтов нет и нет выделеного элемента.
поскольку текущий индекс изменился то срабатывает сигнал currentRowChanged котроый у вас присоединен к self.on_uch
теперь что мы видим(коментарри мои):

 def on_uch(self): # изм учётки
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        # после смены категории уч_index станет = -1
        if уч_index == None:  # это условие никогда не выполниться
            уч_index = None  #  а это вообще бессмыслено , ведь у вас оно и так должно быть None
        else:
            уч_index = self.listWidget_уч.currentRow() # какой в этом смысл? мы же 4 строки назад делаи тоже самое..
            self.pole_адрес.setText(db[кат_index+1][уч_index+1][0])
            # уч_index   у вас -1 вот вы и получили list index out of range
            self.pole_логин.setText(db[кат_index+1][уч_index+1][1])       
            self.pole_пароль.setText(db[кат_index+1][уч_index+1][2])
            self.pole_почта.setText(db[кат_index+1][уч_index+1][3])
            self.pole_имя.setText(db[кат_index+1][уч_index+1][4])
            self.pole_фмл.setText(db[кат_index+1][уч_index+1][5])
            self.pole_дата_откр.setText(db[кат_index+1][уч_index+1][6])
            self.pole_дата_закр.setText(db[кат_index+1][уч_index+1][7])
        print('кат_index = ',кат_index)
        print('уч_index = ',уч_index)

меняете этот кусок
 if уч_index == None:
            уч_index = None
        else:
            уч_index = self.listWidget_уч.currentRow()
на
 if  уч_index >= 0:
и избавляетесь от оутофренж при смен категорий. Правда вам это не сильно поможет

У вас есть def on_st_clear(self): # очистка полей учётки
это правильно, ее нужно вызывать или при смене категории, или в def on_uch когда self.listWidget_уч.currentRow() <0. Второе правильнее. Иначе при смене категорий в лайнедитах будут старые данные.
но дальше у вас бред сивой кобылы:
   
self.pole_адрес = QtGui.QLineEdit()
self.pole_адрес.textChanged.connect(self.on_st_0)
...............
def on_st_0(self):
        кат_index = self.listWidget_кат.currentRow()
        уч_index = self.listWidget_уч.currentRow()
        db[кат_index+1][уч_index+1][0] = self.pole_адрес.text()
        Window().basa_save()
...............
def basa_save(self): # сохранить базу данных
        F_W = open('res/basa3.pkl', 'wb')
        pickle.dump(db,F_W)
        F_W.close()
Во первых: каждый раз когда вы переключаете учетки, меняется текст в лайнедитах, они генерируют textChanged и идет запись на диск. Нахрена? Вы же только что это считали оттуда.
Во второых: если я захочу например изменить каокенибдь поле, то каждый раз когда я буду набирать BackSpace или любой символ, вы будете открывать файл на запись и это записыватьв базу.После каждого нажатия клавиши. Зачем такая нагрузка на дисковую подсистему? А если пользователь случайно удалил символ?? Я бы воббще делал лайнедиты нередактируемымы, а внизу добавил бы две-три кнопки, EDIT - котороая раблокирует поля и SAVE - котороая пишет в базу, ну CANCEL - вернуть все как было(заново перчитать из базы).
В третьих, если вы захотите очистить поле(например при переключении категории) то LineEdit сгенерирет сигнал textChanged , что опять же вызовет запись в БД , НО у вас же self.listWidget_уч.currentRow() = -1, что опять же вызовет “out of range” но уже в
 db[кат_index+1][уч_index+1][0] = self.pole_адрес.text()

Ну и так:
Имена перемнных на кирилице - ЕРЕСЬ
Имена переменных латиница+кирилица ЕРЕСЬ**2





==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Март 14, 2017 14:33:56)

Офлайн

#3 Март 14, 2017 14:22:55

vic57
Зарегистрирован: 2015-07-07
Сообщения: 908
Репутация: +  127  -
Профиль   Отправить e-mail  

PyQt4 | Программа для хранения учётных записей, паролей

Kyrym
вообще ты выбираешь трудные пути какие-то
для хранения таких данных есть базы данных
в питоне есть pysqlcipher для шифрования sqlite, поработай с ним для начала
идти всегда надо от структур данных к GUI, а не наоборот

Офлайн

#4 Март 14, 2017 15:42:08

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQt4 | Программа для хранения учётных записей, паролей

PEHDOM
когда вы делаете listWidget.clear() текущий индекс сбрасываеться в -1
А ведь в логах я видел -1, но не понял откуда он берётся. Теперь одной проблемой меньше )).
PEHDOM
Я бы воббще делал лайнедиты нередактируемымы
На самом деле я так и хотел сделать, но после того, как разберусь с шифрованием.
PEHDOM
каждый раз когда вы переключаете учетки, меняется текст в лайнедитах, они генерируют textChanged и идет запись на диск.
Да, об этом я как-то не подумал… Поправлю.
PEHDOM
Имена перемнных на кирилице - ЕРЕСЬ
Имена переменных латиница+кирилица ЕРЕСЬ**2
Про кириллицу мне везде так говорят, но:
1) с ней всё работает;
2) мне так удобнее
А вообще, спасибо Вам большое за столь обстоятельный ответ.

vic57
в питоне есть pysqlcipher для шифрования sqlite, поработай с ним для начала
На сколько я понял, у sqlite отсутствует мастер-пароль. Или всё-таки есть?

А какую вообще базу данных лучше использовать, если к ней предъявляются требования:
1) бесплатность
2) наличие мастер-пароля
3) для работы с программой не требуется установка дополнительного ПО (или требуется, но без прав администратора)
4) желательна (но не обязательна) хоть какая-то литература на великом и могучем.

Отредактировано Kyrym (Март 14, 2017 15:44:50)

Офлайн

#5 Март 14, 2017 15:51:34

vic57
Зарегистрирован: 2015-07-07
Сообщения: 908
Репутация: +  127  -
Профиль   Отправить e-mail  

PyQt4 | Программа для хранения учётных записей, паролей

Kyrym
На сколько я понял, у sqlite отсутствует мастер-пароль. Или всё-таки есть?
есть ключ к базе данных, без которого она не читается
https://github.com/leapcode/pysqlcipher
работать так же как с sqlite, по ней мануалов полно

Отредактировано vic57 (Март 14, 2017 15:55:05)

Офлайн

#6 Март 14, 2017 15:54:59

MrViktor
Зарегистрирован: 2017-03-09
Сообщения: 83
Репутация: +  8  -
Профиль   Отправить e-mail  

PyQt4 | Программа для хранения учётных записей, паролей

Kyrym
На сколько я понял, у sqlite отсутствует мастер-пароль. Или всё-таки есть?
Смотря что понимать под мастер паролем, для меня это пароль с помощью которого шифруются данные всех учеток в базе, то есть без разницы какая база используется функция шифрования и расшифрования лежит на плечах разработчика, так же как и выбор алгоритма шифрования. Незная этого пароля вся база - это просто мусор.

Офлайн

#7 Март 14, 2017 15:58:49

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQt4 | Программа для хранения учётных записей, паролей

MrViktor
Смотря что понимать под мастер паролем
Главное, чтобы без пароля, нельзя было воспользоваться базой данных + удобство в использовании, а будет ли шифроваться содержимое файла или сам файл - это, как я понимаю, вторично.

Отредактировано Kyrym (Март 14, 2017 16:23:42)

Офлайн

#8 Март 14, 2017 16:05:57

MrViktor
Зарегистрирован: 2017-03-09
Сообщения: 83
Репутация: +  8  -
Профиль   Отправить e-mail  

PyQt4 | Программа для хранения учётных записей, паролей

Kyrym
Главное, чтобы пароля, нельзя было воспользоваться базой данных + удобство в использовании, а будет ли шифроваться содержимое файла или сам файл - это, как я понимаю, вторично.
Ну тогда Вам надо определиться с базой которую будете использовать, написать две функции или одну универсальную для криптования и декриптования. Перед тем как записать данные из полей в базу надо будет их прогнать через крипто функцию, а результат записать в базу. Расшифрование еcтественно наоборот при нажатии к примеру на кнопку “показать пароль” из базы берется значение прогоняется через декрипт функцию и результат в текстбокс.

Отредактировано MrViktor (Март 14, 2017 16:15:46)

Офлайн

#9 Март 14, 2017 16:26:14

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQt4 | Программа для хранения учётных записей, паролей

pycrypto подойдёт для этих целей с учётом поста 4?

Офлайн

#10 Март 14, 2017 17:02:28

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQt4 | Программа для хранения учётных записей, паролей

Kyrym
На сколько я понял, у sqlite отсутствует мастер-пароль. Или всё-таки есть?
Насколько я знаю у любой Embedded БД отсутвует мастер-пароль, Хотя может кто опровергнет?
Любая программа может работать с файлом(-ами) Embedded БД если имеет доступ к нему(и он не занят естественно). Единственный метод защиты это зашифровать всю БД. Вот статейка на хабре. https://habrahabr.ru/post/216739/
но думаю вы не потянете.
Поэтому не партесь, храните в чемнить простом, шифруйте только пароль, ну может логин еще, какимнить pycrypto -ом или simple-crypt -ом. Для “защиты” от любопытного соседа считающего себя кулхацкером вам хватит с головой, а написать программу способную противостоять какой либо хакерской атаке вы всеравно не сможете.

Kyrym
А какую вообще базу данных лучше использовать, если к ней предъявляются требования:
да пофиг, ну сколько у вас будет храниться учетных записей? Сто? Двести? Тысяча? Да хоть в банальной DBF-ке храните , хоть в csv при таких обьемах.

MrViktor
написать две функции или одну универсальную для криптования и декриптования
+ еще одну для глобального криптования-декриптования. например поменяли вы мастерпароль, нужно взять все зашифрованые старым ключем пароли , и перешифровать уже с новым ключем.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Март 14, 2017 17:52:41)

Офлайн

  • Начало
  • » GUI
  • » PyQt4 | Программа для хранения учётных записей, паролей[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version