mystuff22
".
file vault0 | sample run |
user joe shift+vigenere ?5d`54=22d5Boqqv user ann shift+caesar 2018^midGO_NAVY_ data joe vigenere LjTmZ8o*s=CEWyi.q data joe caesar z53y5vJKDIHDHO data ann caesar instrument_french_horn |
~/$ java Vault vault0 username: joe password: ← password not echoed to the screen! Access granted! > labels ssnum combo > get ssnum 892-88-1263 > quit |
This project is designed to exercise your ability to write good Object-Oriented code in Java, which will include good use of encapsulation, data-hiding, inheritance, polymorphism, class hierarchies, interfaces, and exception handling. The project has three main pieces: encryption algorithms, hash algorithms, and the vault. Failing to do a good job of following OOP best-practices in producing your solutions to the first two parts will likely result in difficulty completing the subsequent parts.
*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz
The chosen encryption and hashing algorithms produce results that are in that restricted character set as well. Any encrypted entry in a vault-file and any user-entered label, data, or password that is outside of these bounds is an error and should result in some kind of message.
String
objects, other times as objects of type
char[]
. Just in case you didn't know here's how to convert back and forth:
String str = "foo";
char[] buff = str.toCharArray(); // convert String to char[]
String rts = new String(buff); // convert char[] to String
(int)str.charAt(0) + 7
, or (char)(i + 3)
.
clear
,
caesar
, and
vigenere
(all described later). A Part 1 solution will be a program TestEncryptors that allows the
user to encrypt a test message of their choice using any one of the three algorithms above. The program itself is
not the important product here. Instead, correct implementations of the three encryption algorithms with a single
coherent interface and a well-thought out system of error-handling is the real point.
example 1 | example 2 | example 3 |
~/$ java TestEncryptors algorithm: clear password : grumpy message : This_is_just_test:1234 plain : This_is_just_test:1234 cipher: This_is_just_test:1234 decryp: This_is_just_test:1234 |
~/$ java TestEncryptors algorithm: caesar password : grumpy message : This_is_just_test:1234 plain : This_is_just_test:1234 cipher: y<=G3=G3>IGH3H9GH_VWXY decryp: This_is_just_test:1234 |
~/$ java TestEncryptors algorithm: vigenere password : grumpy message : This_is_just_test:1234 plain : This_is_just_test:1234 cipher: @_ceTg_VdghrKk_ei8nz-w decryp: This_is_just_test:1234 |
Your project will benefit tremendously from following good object oriented design principals. To help you out, I'm going to impose more structure on this first part of the assignment. Here are the rules and recommendations:
Encryptor
providing the
clear
algorithm, which is to not change the plaintext at all.
curl -O http://faculty.cs.usna.edu/IC211/docs/proj2/Encryptor.java curl -O http://faculty.cs.usna.edu/IC211/docs/proj2/Clear.java curl -O http://faculty.cs.usna.edu/IC211/docs/proj2/TestEncryptors.java
caesar
): see
Caesar-shift details.
vigenere
): see
Vigenere details.
algorithm password plaintext ciphertext note clear whale65] 987:test;DOG 987:test;DOG caesar whale65] 987:test;DOG ?>=@zkyzAJUM vigenere whale65] 987:test;DOG 5vn+^q-V7158 clear 10$More 987:test;DOG error $ not allowed in key caesar 10$More 987:test;DOG error $ not allowed in key vigenere 10$More 987:test;DOG error $ not allowed in key clear hone_5^ 1$L0VE$cats$ error $ not allowed in plaintext caesar hone_5^ 1$L0VE$cats$ error $ not allowed in plaintext vigenere hone_5^ 1$L0VE$cats$ error $ not allowed in plaintext
~/bin/submit -c=IC211 -p=project02 *.java
Part 1 of the Project is worth 25 total points, 15 of which are "on the chopping block" for this deadline.
Here's how your submission will be assessed at this intermediate point:
A Part 2 solution is a program TestHashers
that allows the user to hash a test message (which will
be the "password") of their choice using one of the following three algorithms:
clear
,
shift+caesar
, or
shift+vigenere
. The program itself is not the important product here: correct implementations of
the three hashing algorithms with a single coherent interface and a well-thought out system of error-handling is
the real point.
Note: Please take note of the nice design laid out for you for the encryption stuff in Part 1,
and try to do something similar here!
example 1 | example 2 | example 3 |
~/$ java TestHashers algorithm: clear password : grumpy password read : grumpy hash computed : grumpyxxxxxxxxxx |
~/$ java TestHashers algorithm: shift+caesar password : grumpy password read : grumpy hash computed : hxgZorxKIJQw51,` |
~/$ java TestHashers algorithm: shift+vigenere password : grumpy password read : grumpy hash computed : U@P9yh>l0N<;_o]o |
The clear
algorithm takes first 16 characters of the input (add x's to the back to pad out to
16 characters if the message is shorter) as the resultant hash of the input. The shift+
algorithms uses a symmetric encryption algorithm to produce a hash, which gives us shift+caesar
and shift+vigenere
(you could offer shift+clear
if you wanted to): see
shift+ details.
Exceptions: Each of these three hash implementations must throw exceptions when error situations
occur: for the TestHashers program all errors should result in exceptions thrown out of main() and vomited
onto the screen. The types and accompanying messages of these
exceptions should be informative! For example, if the inputted password contains invalid characters, an
exception should be thrown before the program continues to ask for more input.
Important: it's up to you to define a nice hierarchy of exceptions that will allow you to handle
errors nicely in the coming sections.
Test thoroughly! To help you do so, here are some test vectors:
algorithm password hash note clear whale65] whale65]xxxxxxxx shift+caesar whale65] V^n]PehnA?@Gm+xs shift+vigenere whale65] C+HK`8fzqA+4P3Q[ clear 10$more error $ not allowed in key shift+caesar 10$more error $ not allowed in key shift+vigenere 10$more error $ not allowed in key
Vault
that takes a vault-file that contains only "user" entries (format
described below), queries the user for a username and password, and replies with either the message "Access
granted!" or "Access denied!" depending on whether
the username and password pass authentication. If access is granted, the program prints a > prompt and
processes commands ... although the only command it understands is quit
, which immediately quits the
program.
file vault3 | example 1a, 1b | example 2a, 2b | example 3a, 3b |
user chambers clear princessxxxxxxxx user taylor shift+caesar FDELr0,x[csbUjms user hawkins shift+vigenere 7sM7;9/D:@R_c]3i |
~/$ java Vault vault3 username: chambers password: 123456 Access denied! ~/$ java Vault vault3 username: chambers password: princess Access granted! > quit |
~/$ java Vault vault3 username: taylor password: Neural4evr Access denied! ~/$ java Vault vault3 username: taylor password: Cuddly1 Access granted! > quit |
~/$ java Vault vault3 username: hawkins password: G0N4\/y Access denied! ~/$ java Vault vault3 username: hawkins password: OOP-C-day-Z Access granted! > quit |
java Vault
<filename>
, and its prompts and output messages must match the format of the examples above exactly.
This also means that the password should not be echoed to the screen. See TestEncryptors.java for an example
of how to do this.
usage: java Vault <filename>
" and exit.
Error! File 'name' could not be opened.
" and exit.
Error! File 'name' improperly formatted.
" and exit.
(see vault31 for example)Access denied!
" is the proper message for this case.Error! Hash algorithm 'hashalg' not supported.
" and exit.
(see vault32 and login with username=chambers
and password=princess for example)
java Vault -au filenamewhere the -au option indicates that you want to add a user. The user is prompted to enter a username, password, and a hash algorithm as shown in the examples below.
1. file vault4 | 2. add user | 3. new file vault4 | 4. authenticate |
user chambers clear princessxxxxxxxx |
~/$ java Vault -au vault4 username: roche password: Tuba+Time Hash algorithm: shift+caesar |
user chambers clear princessxxxxxxxx user roche shift+caesar *0TRSZ/>:5iq0pcx |
~/$ java Vault vault4 username: roche password: Tuba+Time Access granted! > quit |
We haven't really done anything with writing files yet. Here's some example code. Note that you need to make sure to close the file. That's important. You'll also want to make sure you close the input file immediately after reading it at the beginning of your program. There are two options for you. The first is to overwrite the file, the second is to append to the end of an existing file.
// Creates a new file and clobbers the existing one.
PrintWriter pw = null;
try {
pw = new PrintWriter(new File(fname));
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
// Do whatever you need to do
if (pw != null) pw.close();
// Opens an existing file, and appends to the end of it.
PrintWriter pw = null;
try {
pw = new PrintWriter(new BufferedWriter(new FileWriter(filename, true)));
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
// Do whatever you need to do
if (pw != null) pw.close();
Obviously, we're adding functionality to your Part 3 solution, so all the part three stuff should work as before. The only really new things are:
usage: java Vault [-au] <filename>
"
Error! Invalid symbol 'x' in password.
" and exit.Error! Hash algorithm 'hashalg' not supported.
" and exit.Error! Username 'username' already in use.
" and exit.Note: Writing to files is a bit new. PrintWriter objects give you your usual print, println and printf. In the sample code above on the left, when a new user is added, you completely overwrite the vaultfile. That means you have to write entries for all the existing users as well as for the new user. You will want to read and save the entire file in memory first, and then create a PrintWriter to write to that same file that you just read.
data username encalg cipertextwhere encalg can be one of
clear
,
caesar
, or
vigenere
, and ciphertext is a ciphertext-string that decrypts (with the user's
password as key and using encryption algorithm encalg) to a plaintext string of the form
label_
text, where both the label and the text come from the ASCII range
42-122, but the label does not include the '_' character. For example, suppose there is a user crabbe with
password FlappyBirds. We might have
a data entry like this:
data crabbe caesar ,//=0>>*j@8-0=*P*c=48,@7/*l7J Note: decrypt with caesar and password FlappyBirds gives: address_Number_4_Grimauld_Pl. \_____/ \___________________/ label textThis means that the entry represents the label "address" with the associated text "Number_4_Grimauld_Pl.".
file vault5a | sample run 1 | vault5b | sample run 2 |
user chambers clear princessxxxxxxxx data chambers clear weakness_backhand data chambers caesar bZa`WQwtspu+vpyyxx data chambers vigenere [XdX*Kf\TF\XG.ajZZb\WX |
~/$ java Vault vault5a username: chambers password: princess Access granted! > labels weakness phone faveBand > get weakness backhand > get faveBand One_Direction > quit |
user chambers shift+caesar /+wZbraTilrECDKq user taylor shift+vigenere 5[0E,;d2rp;M8[0: data chambers vigenere [XdX*Kf\TF\XG.ajZZb\WX data taylor caesar 43/@-b=C:@=>6=07/ data chambers caesar bZa`WQwtspu+vpyyxx |
$ java Vault vault5b username: taylor password: Neural4evr Access granted! > labels fear > get fear Coulrophobia > get faveBand > done Unknown command 'done'. > quit |
Note: try the file vault5c, logging in as user taylor with password Neural4evr. If you give the labels command, the last entry for user taylor should give this kind of error.
add encalg label textThis command should add a data entry for the current user, with the encryption algorithm given by encalg, and form the ciphertext by encryption label
_
text with algorithm encalg using the password the user
authenticated with as the key for the encryption.
file vault6a before | sample run | file vault6a after |
user chambers clear princessxxxxxxxx user roche shift+caesar *0TRSZ/>:5iq0pcx data roche caesar dgn]WZac]Wja\af_ |
$ java Vault vault6a username: roche password: Tuba+Time Access granted! > add vigenere ssnum 123-45-6789 > quit |
user chambers clear princessxxxxxxxx user roche shift+caesar *0TRSZ/>:5iq0pcx data roche caesar dgn]WZac]Wja\af_ data roche vigenere LmU[n8punW.md7aw+ |
~/$ java TestHashers algorithm: shift+vigenere password : ThisIsExactly_16 password read : ThisIsExactly_16 hash computed : 4rgZDs.8u1bjr5A/ |
~/$ java TestHashers algorithm: shift+vigenere password : ThisIsExactly_16_plus_some password read : ThisIsExactly_16_plus_some hash computed : K>0F_<6vvHfYP:c^ |
README
with your name and alpha code, which step you are submitting for
(including any extra credit), and any issues you know your program has.
Your paper submission must include:
~/bin/submit -c=IC211 -p=project02 *.java README