key_encryption: Encryption is a way to mask information by transforming it so that it appears to be different random data. An encryption algorithm is used to encrypt the data, similarly, the reverse algorithm is applied to decrypt the actual data from the encrypted data. Following is an algorithm that you will implement for encryption/decryption:
- Swap the t-th character from start to the t-th character from end.
i.e. if t = 3, “COSC-2306-Spring-DP” → “CO-C-2306-SpringSDP”
Note that, ‘t’ must in “0 < t < len(key)”, otherwise do nothing.
- Apply a shift of 'k' to each digit and alphabet: (similar to 'shift cipher' concept)
right-shift if 'k > 0' : when k = 2, { A → C, ... , Z → B; 0 → 2, …, 9 → 1}
left-shift if 'k < 0' : when k = -2, { Y ← A, ... , X ← Z; 8 ← 0, …, 7 ← 9}
and do nothing if 'k = 0'.
i.e. if k = 2, “CO-C-2306-SpringSDP” → “EQ-E-4528-UrtkpiUFR”
- Flip the case of alphabets, lower to upper and upper to lower.
i.e. “EQ-E-4528-UrtkpiUFR” → “eq-e-4528-uRTKPIufr”
- Finally, reverse the string, and return.
i.e. “eq-e-4528-uRTKPIufr” → “rfuIPKTRu-8254-e-qe”
key_decryption: Decryption applies the reverse steps of the encryption algorithm to get actual data from the encrypted data. Therefore, someone who knows this encryption algorithm can easily decrypt the data.
def key_encryption(actual_key, t, k): pass
def key_decryption(encrypted_key, t, k): pass
Complete all TODO, you will use this HashTable class from hashing_with_chaining() and verifying_hashing().
Follow below steps to implement the hash(key), that finds desired bucket by user_id:
- Calculate the summed ASCII value of characters in key.
Note that python has ord() function to get the ASCII value of a character.
i.e. “Paul” → 80 + 97 + 117 + 108 = 402
- Suppose, ‘n’ is the size of a hash table, in other words, the hash table has ‘n’ buckets.
Find the desired bucket using modulo operator (%):
i.e., bucket = (sum % n) + 1
i.e. if n = 4, (402 % 4) + 1 = 3 (desired bucket number)
Example of Hash Table: display()
1-th Bucket: [(User1, HashedPass1, Salt1), (...), ...]
2-th Bucket: [...]
3-th Bucket: [(User3, HashedPass3, Salt3), (...), ...]
4-th Bucket: [...]
...
class HashTable:
def __init__(self, hash_size):
self.n = hash_size
self.buckets = [[] for _ in range(hash_size)]
def hash(self, key):
# TODO:
# Calculate the summed ASCII value of characters of key.
# Return the desired bucket number using the modulo operator(%). pass
def put(self, key, value):
# TODO: Call hash() to get desired bucket number, add value to bucket, and return True. pass
def get(self, key):
# TODO: Call hash() to get desired bucket number, get value from bucket by key,
# and if found return (bucket_number, bucket_index, value), else return None. pass
def display(self):
# TODO: Display hash table in given format. pass
The hash value of the same string should always be the same. Therefore, users having the same passwords will result in having the same hash value generated. This is not secure in case a hacker gets their hand on a valid password-hash value combination: in this scenario, then the hacker would be able to at least know what users are using the same password. To make a more secure system, a random unique string, called Salt, is added with the password (i.e. key = password + salt) and then the hash value is calculated. Thus, users having the same passwords have the different hash values generated for different salt values. Runestone doesn’t support any built-in hash library yet, therefore, in this assignment, you will define a custom hash function to get the hash value for a key (= password + salt). Use the following algorithm as password hash function (here, password and salt have been passed as arguments):
Initially, set "h = 1"
For each character in key: (here, key = password + salt)
compute "42*h + ord(c)" and add to 'h'
Return 'h'
def hashing_with_salting(password, salt):
# TODO: concat password and salt as key, compute hash value
# based on the algorithm, and return it. Pass
For each user, after generating the hashed password (using hashing_with_salting), your next goal is to store them in a hash table (use HashTable class) for faster access. Follow the below rules (use put() of HashTable class) to save the hashed passwords into different buckets of hash table:
- Generate the hashed password (use hashing_with_salting()).
- Encrypt the salt value (use data_encryption()).
- Append value (user_id, hashed_password, encrypted_salt) into the desired bucket (use put() of HashTable class).
Example: Display Hash Table (bucket numbering starts from 1)
1-th Bucket: [('User1', 110614699040027587622, 'B_5r'), ('User5', 107680145621891915755, 'o1*D')]
2-th Bucket: []
3-th Bucket: [('User3', 130067078622569130997, 'Z4z@')]
4-th Bucket: []
def hashing_with_chaining(user_list, hash_table, t, k): assert isinstance(hash_table, HashTable)
# TODO: for each user,
# generate the hashed password (use hashing_with_salting())
# encrypt the salt value (use data_encryption())
# append value into bucket (use hash_table.put())
# display hash value and hash table (expected unittest format) pass
After saving all values into the hash table, it would be much easier and efficient to verify the hashing. The steps are following:
- Suppose, credentials (user_id, password) are given.
- Retrieve value from bucket based on user_id (use get() of HashTable class).
- Generate the actual salt value from encrypted_salt_value (use data_decryption()).
- Compute the target hash password (use hashing_with_salting()).
- Compare this computed target hash password with the retrieved hash_password.
Print the verifying message in below formats:
Verifying (ID: Alice, Password: K*c23Ze*): Failed.
User not found.
Verifying (ID: User1, Password: GNl8j6*$): Failed.
Computed hash value (107680145621890557129) does not match with expected hash value (110614699040027587622).
Verifying (ID: User5, Password: GNl8j6*$): Success.
Hash value (107680145621891915755) matched at index-1 of Bucket-1.
...
def verifying_hashing(credentials, hash_table, t, k):
# here, hash_table is an instance of HashTable
# TODO: first display the hash table,
# then verify credentials hashing pass
CS 340 Milestone One Guidelines and Rubric Overview: For this assignment, you will implement the fundamental operations of create, read, update,
Retail Transaction Programming Project Project Requirements: Develop a program to emulate a purchase transaction at a retail store. This
7COM1028 Secure Systems Programming Referral Coursework: Secure
Create a GUI program that:Accepts the following from a user:Item NameItem QuantityItem PriceAllows the user to create a file to store the sales receip
CS 340 Final Project Guidelines and Rubric Overview The final project will encompass developing a web service using a software stack and impleme