· 9 years ago · Jan 30, 2017, 04:26 PM
1from tkinter import *
2import tkinter.messagebox
3import pymysql
4import uuid
5import hashlib
6
7# salausfunktiot
8# http://pythoncentral.io/hashing-strings-with-python/
9
10def hash_password(password):
11 # uuid is used to generate a random number
12 salt = uuid.uuid4().hex
13 return hashlib.sha256(salt.encode() + password.encode()).hexdigest() \
14 + ':' + salt
15
16def check_password(hashed_password, user_password):
17 password, salt = hashed_password.split(':')
18 return password == hashlib.sha256(salt.encode() + \
19 user_password.encode()).hexdigest()
20
21
22# käytetään alla olevaa MYSQL-tietokantaa ja yhtä taulua
23#
24# edelliseen verrattuna kasvatettu salasanan pituutta, koska
25# kryptattu salasana on tavallista pidempi
26
27"""
28CREATE DATABASE koekanta1;
29
30CREATE TABLE IF NOT EXISTS `koekanta1`.`Tunnustaulu` (
31 `tunnusID` INT NOT NULL AUTO_INCREMENT,
32 `tunnus` VARCHAR(8) NOT NULL,
33 `salasana` VARCHAR(1024) NOT NULL,
34 PRIMARY KEY (`tunnusID`),
35 UNIQUE INDEX `tunnus_UNIQUE` (`tunnus` ASC));
36"""
37
38# MySQL-palvelimen kirjautumistiedot
39PALVELIN='192.168.99.99'
40MYSQLKAYTTAJA='python'
41MYSQLSALASANA='python'
42TUNNUSTIETOKANTA='koekanta1'
43
44# Muutama testitunnus
45testitunnukset = [["testeri1","salasana1"],
46 ["testeri2","salasana2"],
47 ["testeri3","salasana3"]]
48
49class Kirjautumisikkuna:
50 def __init__(self):
51 self.__ikkuna=Tk()
52 self.__ikkuna.title("Syötä käyttäjätunnus ja salasana")
53 self.__label_tunnus=Label(self.__ikkuna,text="Käyttäjätunnus:")
54 self.__entry_tunnus=Entry(self.__ikkuna,width=24)
55 self.__label_salasana=Label(self.__ikkuna,text="Salasana:")
56 # show="*" näyttää salasanan merkit tähtinä
57 self.__entry_salasana=Entry(self.__ikkuna,width=24,show="*")
58 self.__nappi_kirjaudu=Button(self.__ikkuna,
59 text="Kirjaudu",
60 command=self.kirjaudu)
61 self.__label_tunnus.grid(row=0,column=0,sticky='W')
62 self.__entry_tunnus.grid(row=0,column=1)
63 self.__label_salasana.grid(row=1,column=0,sticky='W')
64 self.__entry_salasana.grid(row=1,column=1)
65 self.__nappi_kirjaudu.grid(row=2,columnspan=2)
66
67 mainloop()
68
69 def kirjaudu(self):
70 tunnus=self.__entry_tunnus.get()
71 salasana=self.__entry_salasana.get()
72 if len(tunnus)==0 or len(salasana)==0:
73 messagebox.showinfo("VIRHE", "Käyttäjätunnus ja salasana ei kelpaa")
74 else:
75 tunnusID=tarkasta(tunnus,salasana)
76 if tunnusID==None:
77 messagebox.showinfo("VIRHE","Kirjautuminen epäonnistui")
78 else:
79 messagebox.showinfo("Kirjautuminen OK",\
80 "tunnusID={0}".format(tunnusID))
81
82def tarkasta(kirjautumistunnus,kirjautumissalasana):
83
84 jatketaanko=False
85
86 try:
87 # aukaistaan kanta
88 conn = pymysql.connect(host=PALVELIN,
89 port=3306,
90 user=MYSQLKAYTTAJA,
91 passwd=MYSQLSALASANA,
92 db=TUNNUSTIETOKANTA)
93 jatketaanko=True
94 except Exception as e:
95 print("Yhteyden aukaisu tietokantaan epäonnistui")
96 print(str(e))
97 if jatketaanko:
98 try:
99 cur = conn.cursor()
100 cur.execute("SELECT * FROM Tunnustaulu")
101 except Exception as e:
102 print("Virhe luettaessa tietokantaa")
103 print(str(e))
104 jatketaanko=False
105 conn.close()
106 if jatketaanko:
107 # jos kanta on tyhjä, niin lisätään testitunnukset
108 if cur.rowcount==0:
109 for rivi in testitunnukset:
110 # salataan kantaan tallennettavat salasanat
111 # käyttämällä Python Centralin valmista
112 # hash_password()-funktiota, joka käyttää
113 # sha256 ja satunnaislukua, mikä saadaan
114 # uuid-kirjastosta
115
116 sql="INSERT INTO Tunnustaulu(tunnus,salasana) "\
117 "VALUES ('{0}','{1}')"\
118 .format(rivi[0],hash_password(rivi[1]))
119 try:
120 cur.execute(sql)
121 conn.commit()
122 print("Tunnus",rivi[0],"lisätty tietokantaan")
123 except Exception as e:
124 conn.rollback()
125 print("Tapahtui virhe suorittaessa SQL-komentoa:\n",sql)
126 print(str(e))
127
128 # varsinainen tunnuksen ja salasanan tarkastus
129
130# ilman salausta
131# sql="SELECT tunnusID FROM Tunnustaulu WHERE "\
132# "tunnus = '{0}' AND salasana = '{1}'"\
133# .format(kirjautumistunnus,kirjautumissalasana)
134
135# salauksen kanssa
136 # haetaan kannasta käyttäjätunnuksen perusteella tunnusID
137 # ja sha256-koodattu salasana
138 sql="SELECT tunnusID,salasana FROM Tunnustaulu WHERE "\
139 "tunnus = '{0}'"\
140 .format(kirjautumistunnus)
141 kirjautumistunnusID=None # palautettava ID-numero tauluun
142 try:
143 cur.execute(sql)
144 # jos löytyi yksi käyttäjätunnus, niin tarkastetaan salasana
145 if cur.rowcount==1:
146 hakurivi=cur.fetchone()
147 # käytetään Python Cenralin check_password-funktiota
148 # salasanan tarkastukseen, hakurivi[1] on kannasta
149 # saatu krypattu, ja kirjautumissalasana käyttäjän
150 # ikkunaan kirjoittama salasana
151 if check_password(hakurivi[1],kirjautumissalasana):
152 kirjautumistunnusID=hakurivi[0]
153 except Exception as e:
154 print("Tapahtui virhe luettassa tietokantaa")
155 print(str(e))
156 cur.close()
157 conn.close()
158 return kirjautumistunnusID
159
160# käynnistys
161kirjautumisikkuna = Kirjautumisikkuna()