I am learning sqlite3 and I tried inserting an rsa key into one of my columns that I made but I get this error:
sqlite3.InterfaceError: Error binding parameter 2 - probably unsupported type.
Here's my code:
import sqlite3, rsa
db = sqlite3.connect('database.db')
db.execute('drop table if exists user')
db.execute('create table user (username text, password text, pubKey tuple,
privKey tuple)')
username = input("Input Username: ")
password = input("Input Password: ")
confirm = input("Confirm Password: ")
(pubKey, privKey) = rsa.newkeys(512)
if password == confirm:
db.execute('insert into user (username, password, pubKey, privKey) values (?, ?, ?, ?)', (username, password, pubKey, privKey))
db.commit()
else:
quit()
I am using rsa.newkeys to generate the keys and they generate as tuples. For example the tuple will be something along the lines of:
PublicKey(7993225774562669856453147392958346571937702133919317490212017912216372852796080413531673713173968180340315460310318908937895213458133041784535151317298739, 65537)
I looked at the documentation for rsa and rsa.newkeys() dpes return a tuple but I get the error saying it is the wrong data type.
pubKey and privKey are instances of the classes (rsa.key.PublicKey and rsa.key.PrivateKey)
From the instance you could take both vallues as int:
pubKey.n - from your example it's 7993225774562669856453147392958346571937702133919317490212017912216372852796080413531673713173968180340315460310318908937895213458133041784535151317298739
pubKey.e - it's 65537
If you need only the keys, save int to the db:
db.execute('create table user (username text, password text, pubKey int, privKey int)')
...
db.execute('insert into user (username, password, pubKey, privKey) values (?, ?, ?, ?)', (username, password, pubKey.n, privKey.n))
If you need a whole string, convert to str and save as text:
db.execute('create table user (username text, password text, pubKey text, privKey text)')
...
db.execute('insert into user (username, password, pubKey, privKey) values (?, ?, ?, ?)', (username, password, str(pubKey), str(privKey)))
Take a look at your RSA key - it's probably hex (i.e. there are numbers AND letters) so int will not work. Int is for numbers only.
I'd suggest either using text or blob for the type.
Related
I am using Python and MySql to handle user authentication. I have added the users thru python with the exact same method, but when I try to do the "login"/authentication it does not match.
This is my code for authentication:
# Collecting data from users.
username=data['username']
password=data['password']
cur=mysql.connection.cursor()
# Checks if username exists.
check_username = cur.execute("SELECT * FROM `users` WHERE `username`=%s",[username])
if check_username > 0:
# Retrieves the correct salt of the user.
cur.execute("SELECT `salt` FROM `users` WHERE `username`=%s",[username])
get_salt = cur.fetchone()
# Generates the hashed password of the user.
hashed_password=(hashlib.sha256((str(password[0:2])+str(get_salt[0])+str(password[2:])).encode('utf-8')).hexdigest()).lower()
# Retrieves the hashed password of the user from the database.
cur.execute("SELECT `password` FROM `users` WHERE `username`=%s",[username])
get_password = cur.fetchone()
# Checks if identical.
if get_password[0] == hashed_password:
return jsonify("Authentication successful!"),201
else: return jsonify("Authentication failed!"),401
else: return 'Incorrect username. Please try again.'
The hashed_password does not return the same hashed password that is stored in the database.
And this is the code I used to insert the users.
username=data['username']
password=data['password']
salt=data['salt']
cur=mysql.connection.cursor()
# Generates the hashed password of the user.
hashed_password=(hashlib.sha256((str(password[0:2])+str(salt[0])+str(password[2:])).encode('utf-8')).hexdigest()).lower()
# Adds user to database.
add_user = cur.execute(" INSERT INTO `users` (`username`, `password`, `salt`) VALUES (%s, %s, %s);",[username,hashed_password, salt])
Does anyone see what is causing this?
Looking at the insertion code, you seem to treat salt like the get_salt tuple, get first item, not knowing what it is originally, that might be the source of your issues as I would not expect the first salt you get to be in a tuple.
Here is a version that works, it's using SQLite rather than MySQL, but the changes are minimal besides formatting.
Also, I recommend you use hashlib.hash.update() rather than your large and complicated one step hashing. And by default hexdigest is lowercase, so no need to .lower() it.
# db setup
import hashlib
import sqlite3
con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("CREATE TABLE users (username TEXT, salt TEXT, password TEXT)")
in_username = "ljmc"
in_salt = "verysecuresalt"
in_password = "p4assW0rD1!"
h = hashlib.sha256()
h.update(str(in_password[:2]).encode("utf-8"))
h.update(str(in_salt).encode("utf-8")) # here salt[0] is just b"v" not the whole salt
h.update(str(in_password[2:]).encode("utf-8"))
in_hashed_password = h.hexdigest()
cur.execute(
"INSERT INTO users VALUES (?, ?, ?)",
(in_username, in_salt, in_hashed_password), # then store whole salt
)
con.commit()
# user check
username = in_username
password = good_password
# Checks if username exists.
check_username = cur.execute(
"SELECT COUNT(*) FROM users WHERE username = ?", [username]
).fetchone()
if check_username[0] > 0:
# Retrieves the correct salt of the user.
cur.execute("SELECT salt FROM users WHERE username=?", [username])
get_salt = cur.fetchone() # get the whole salt
# Generates the hashed password of the user.
hashed_password = (
hashlib.sha256(
(str(password[0:2]) + str(get_salt[0]) + str(password[2:])).encode(
"utf-8"
)
).hexdigest()
).lower() # use the whole salt
# Retrieves the hashed password of the user from the database.
cur.execute("SELECT password FROM users WHERE username=?", [username])
get_password = cur.fetchone()
# Checks if identical.
if get_password[0] == hashed_password:
print("Authentication successful!")
else:
print("Authentication failed!")
As pointed out by other comments, it would also be a lot better to fetch all the user data in one query and then apply the logic, so the check block would look like this.
cur.execute(
"SELECT username, salt, password FROM users WHERE username = ?",
(username,),
)
if user := cur.fetchone():
out_username, out_salt, out_password = user
h = hashlib.sha256()
h.update(str(password[:2]).encode("utf-8"))
h.update(str(out_salt).encode("utf-8"))
h.update(str(password[2:]).encode("utf-8"))
print(f"is the password {password} ?", out_password == h.hexdigest())
I have a table "Users" with the column "g_score". The other column I am storing are "username". I am trying to send an update to g_score via the username I get. I send the request and the value does not update. g_score is stored as an INT. I am looking to increment the value by + 1 each time.
The g_score value is default = 0
The value is not being updated by the following code
I'm going to leave some snippets here-
Creating the table -
cursor.execute("CREATE TABLE IF NOT EXISTS Users(username TEXT,hash TEXT,salt TEXT,g_score INT)")
If the user does not exist- we do
cursor.execute("INSERT INTO Users VALUES(?, ?, ?, ?)", (username, hashed_password, salt, 0))
This following code does not update the g_score-
db = lite.connect('log.db', check_same_thread=False)
cursor = db.cursor()
sql = ("UPDATE Users SET g_score = g_score + 1 WHERE username = ?")
cursor.execute(sql, [g_winner.get_name()])
import sqlite3
con=sqlite3.connect("mydbmb")
con.execute('''CREATE TABLE IF NOT EXISTS LOGIN
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
NAME TEXT NOT NULL,
ROLL INT NOT NULL,
photo BLOB NOT NULL,
phone INTEGER NOT NULL,
father TEXT NOT NULL,
PASS TEXT NOT NULL);''')
with open("7.jpg", 'rb') as file:
blobdata = file.read()
quer=f'''INSERT INTO LOGIN(NAME,ROLL,photo,phone,father,PASS) VALUES('ADMIN','000','{blobdata}','678642873','GHHGJH','ADMIN123')'''
con.execute(quer)
print("query executed succsessfully")
user_list()
con.close()
Using literal parameters values (i.e. putting the values in the query) is error prone and insecure (unless they are constant)
It is much better to use bound parameters :
quer = '''INSERT INTO LOGIN(NAME,ROLL,photo,phone,father,PASS) VALUES(?, ?, ?, ?, ?, ?)'''
con.execute(quer, ('ADMIN','000', blobdata,'678642873','GHHGJH','ADMIN123'))
print("query executed successfully")
as you can see in this code I have imported my pyqt5 .ui file and I take inputs from users. then when I want to insert it inside the table that I have created using sqlite3, I want the email address to be unique and for that, I wanna check all the rows and find where the email address equals the input I got from the user. if yes then it will show a message. But the code is not working. conn.execute("select * from users where email=?", str(email)), this the part where I wanna check if I have the same email address inside the database or not and the problem is here it ain't working.
def signup(self):
conn = sqlite3.connect("inventory.bd")
conn.execute('''CREATE TABLE IF NOT EXISTS users(
id integer primary key AUTOINCREMENT,
username text not null,
email text not null unique,
password text not null
)''')
username = self.lineEdit.text()
email = self.lineEdit_3.text()
password = self.lineEdit_2.text()
confirm_pass = self.lineEdit_4.text()
res = conn.execute("select * from users where email=?", str(email))
if username == "" or email == "" or password == "":
QMessageBox.about(Dialog,"warning","Please make sure that you have filled all the information")
#QMessageBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
elif (len(res.fetchall())>0):
QMessageBox.about(Dialog, "warning", "The email you have entered has already been used")
elif password != confirm_pass:
QMessageBox.about(Dialog, "warning", "The password does not match!")
else:
conn.execute("insert into users(username,email,password) values(?, ?, ?)", (username, email, password))
conn.commit()
conn.close()
QMessageBox.about(Dialog,'welcome','Your account has been created successfully')
Instead of :
res = conn.execute("select * from users where email=?", str(email))
Try this style of formatting :
res = conn.execute("select * from users where email=%s", email)
Works very well with database queries....
Theory :
Python uses C-style string formatting to create new, formatted strings. The "%" operator is used to format a set of variables enclosed in a "tuple" (a fixed size list), together with a format string, which contains normal text together with "argument specifiers", special symbols like "%s" and "%d".
Here are some basic argument specifiers you should know:
%s - String (or any object with a string representation, like numbers)
%d - Integers
%f - Floating point numbers
in my database I'm using raw_input to allow users to enter data into a database, the problem is that I have an ID assigned to each record of data that is the primary key of the table.
username = raw_input("What would you like your username to be? ")
email = raw_input("What is your email address? ")
firstName = raw_input("What is your first name? ")
surname = raw_input("What is your surname? ")
age = raw_input("How old are you? ")
password = raw_input("What is your password?") #Encryption method will be added later
age = int(age) #Changing the age variable into an integer so it can be inputted into the database
#DB part
conn = db.connect('apollo.db') #Connecting to the database
cursor = conn.cursor()
cursor.execute("INSERT INTO users VALUES(?, ?, ?, ?, ?, ?)",
(username, email, firstName, surname, age, password)) #Inserting the user's data into the table
conn.commit() #Committing the changes
conn.close() #Closing the connection
I assumed that because the primary key increments automatically that it would not be needed to be added into the code because each record would automatically get a number. The problem is, I get this error message when I've answered all of the raw_input questions:
sqlite3.OperationalError: table users has 7 columns but 6 values were supplied
Is there something I need to add to the code for the primary key?
I guess the problem is this:
cursor.execute("INSERT INTO users VALUES(?, ?, ?, ?, ?, ?)",
Try this exchange of that:
cursor.execute("INSERT INTO users (username, email, firstName, surname, age, password) VALUES ",
(username, email, firstName, surname, age, password))
and i think this link can explain it more for you my friend.