C++代写:CS27355 Password Security

使用SHA1算法验证Hash值,校验数据库后,判断密码及其他字段是否被修改。

Background

For this project we are shifting our attention to pointers, structs and arrays of structs. The main focus of this project is to react to the storage demands of our program and “grow” our arrays when they are full.

Context

Sit down and let me tell you a story; a story about a bank with terrible security. Every night Bank XYZ gets hacked. Every night an unknown attacker gains access to the main account file on the bank’s computer. The attacker has the ability to modify the record in any way they wish. Luckily for us, this attacker attended a school other than VT and they are not aware of the signed hash code at the end of the record and they make no effort to hide their tracks. Mainly they are after the vast store of gold in each of the account holder’s accounts.

So your job as the bank’s main super hero, also known as the system admin, is to check each day for hacked records. When this occurs you then generate a report of which accounts were hacked, update their password, thus saving the account holders, and the bank, many thousands of lost pounds of gold. You also have the ability to add new accounts, remove old accounts, and of course save an updated account file.

Details

The program you run each day responds to a series of commands. The commands may have options you can specify. The options depend on the command. The commands will be listed below. Each command has output. Some of the commands many not be successful and there are messages that correspond to those as well.

Commands

load filename

This is the main way data is entered into our system. The load command is followed by a filename. The filename is a csv file of records. The records will be described below. The output from the load command is the filename that was loaded and how many records were loaded.

locked

This command takes no options. It’s job is to go through the list and see which records were hacked. If any records were hacked, then a list of those records is produced. If no records are hacked, then an output message indicating that is given.

unlock id new password

This command will attempt to unlock the given account by it’s id. If the id is found, the password is checked to see if it meets our high standards. If the password is up to our security standards, the records is unlocked, the password is updated, and the signed hash is recomputed using the new data. There are two error conditions that can occur. 1. The account id is not found. In this case, a simple message about not finding that account is given. 2. The account is found, but the password is not secure enough. In this case, the account remains locked, the password is not updated, and there is a message about not unlocking the account.

add new record information

This record format matches the ones in the file, except it does not have a signed hash code at the end. The record is parsed and if the password is up to our security standards, then the account is added to our array at the end. If the password does not meet our standards, then the account is not added.

remove id

This will attempt to remove the record from the array. If the id is found, we will slide down the “higher” accounts down an index position to “cover up” this record. If the id is not found nothing is done. If the record is removed, a message indicating that is given, and if not, a message indicating that the id was not found is issued.

save filename

This will save the array into the given file name. The format needs to match the load file format in this way, you could reload a saved file. Any new or removed records will appear or not in the saved file. The output of this is the file you are using for saving and the number of records saved into the file.

Data

The data in this project is CSV data. It will consist of “records” in the following format:

name,id,account,username,password,signedhash

The name is a string. It will contain spaces. The id is just that, an identifier for the record. Each record will have a unique id and it can be used for searching for the record on an update or removal. The account is a made up bunch of numbers attempting to represent a bank account number. It is purely fictional. Do not go to Bank XYZ and attempt to access any of these accounts. The username is also made up. I’ve just jammed together the person’s name.

The password is also made up. It has to adhere to the set of rules below. The signed hash is more interesting and will be described in more detail below. In a nutshell, it’s a bunch of letters that have been bit manipulated to produce an int.

Password Rules

The rules for the password are fairly straightfoward, they are as follows:

  1. The password must be at least 10 characters.
  2. The password must contain at least one of each of the following types of characters, upper case letter, lower case letter, a number and a punctuation character.

To determine the characters I suggest looking at the cctype (Links to an external site.) library over at cplusplus.com (Links to an external site.) and in particular look at the isupper, islower, ispunct and isdigit functions.

Hashing

Okay so in our records at the end there’s this strange number and I keep talking about this hashing then signing it. This is a basic attempt at some security. We are going to be using a hashing algorithm known as SHA1. The basic idea of SHA is to take a message and produce a hash or a condensed version of the message. Then we will “sign” the message using a sign function. The function will essentially take the message and a key and produce an integer value. This integer will vary per record and gives a primitive way to see if a record was tampered with.

Here’s how I call them in my code:

1
2
3
4
5
6
7
string message;
message = r.name+r.id+r.account+r.username+r.password;
SHA1 checksum;
checksum.update(message);
r.hash = checksum.final();

r.verifiedHash = sign2( r.hash, r.id );

So the code above is from my code and my struct is called Record and r is a variable of my Record struct. My struct contains the fields that are shown in the above code (and some that aren’t shown). verifiedHash is an unsigned int and the rest of what is shown are all strings.

So you can see from the code here, I store the hash and the signedHash in my record. You do not need to do that but you are welcome to do so. Also in this function, r is a variable of type Record, where Record is the name of my struct.

Okay, yes, the header file is named SHA1.hpp. This is okay. hpp is just a header for C++. Move the files into your directory with your project. Add them to your project and all should be fine. You will not need to add sha1.hpp to your zip when you submit. You will need to add the sha1.cpp to your zip.

This main.cpp is a simple piece of code that should run in your Visual Studio. It shows how to create a SHA1 object and how to call the methods to update and finalize the hash and also how to call the sign2 function. It shows the data types of each of the parameters and return types.

Requirements

  1. You must declare a function with the signature void bankAdmin(string commands, string output ); in a file named bank.h
  2. You must create a struct to store the information in the file. You may add fields that are not stored, e.g. a field to indicate locked, a field to store the hash and the signed hash, etc.
  3. You must use a dynamically allocated array of structs to store the data. (*) See below for details about if you choose not to do this.
    • If you can’t get the dynamic array working, you may use a static array, but you won’t get a grade higher than an 80.
  4. You may not use classes for this.
  5. You may not use Vector, List, or any of the other STL storage containers.
  6. No global variables!
  7. You must implement a function for each of the commands.
  8. No global variables! (Yes twice)
  9. You must follow the Code Style Guidelines on Canvas.
  10. You array must start at size of 10 and double when it is full.
  11. Hmm…more?

Grading

Zip up your bank.h and bank.cpp and any other files you wrote. and turn them in to Web-CAT before you go home to eat turkey, or just sleep all week. Don’t forget to use the include guards around your struct and also you will need to add the sha1.cpp to your zip.