You may find the term project assignment in this link
Note: In the project, due to measure the performance, there are 3 different types of files that will be encrypted/decrypted/signed/verified.
One-page-length is the file type which contains only one page characters
Ten-page-length is the file type which contains ten page characters
....
This is my cryptography term project which implemented stage by stage during the spring term of Cryptography 471(2019). This project includes:
- AES or DES with Diffie-Hellman Scheme
- RSA Scheme
- DSS(Digital Signature Signing and Verification) Scheme
To implement these schemes, I also implemented following properties/algorithms/procedures:
To run any stage, just uncomment the following statements in the Main.java:
public class Main {
public static void main(String [] args){
//DiffieHellmanScheme.startDiffieHellmanScheme();
//RSAScheme.startRSAScheme();
//DSSScheme.startDSSScheme();
}
}
First of all, I created PerformanceMeasurement
singleton instance to measure performance of the encryption/decryption process
In this stage, we were free to choose AES or DES. I chose the DES to encrypt & decrypt the files. You may find DESEncryption.java
- Create a unsecure channel which represents the Internet
DiffieHellmanUnsecureChannel unsecureChannel = new UnsecureChannel();
- Then set the prime number(p) and alpha number(a), these are the public numbers and I will need these number for Diffie-Hellman Key exchange
unsecureChannel.diffieHellmanSetup();
- Create the sender and receiver parties and set the prime number(p) and alpha number(a)
Person sender = new Sender();
sender.setPrimeNumber_p_from_unsecureChannel(unsecureChannel.getPrimeNum_p());
sender.setAnyNumber_alpha_from_unsecureChannel(unsecureChannel.getAnyNum_alpha());
Person receiver = new Receiver();
receiver.setPrimeNumber_p_from_unsecureChannel(unsecureChannel.getPrimeNum_p());
receiver.setAnyNumber_alpha_from_unsecureChannel(unsecureChannel.getAnyNum_alpha());
- Sender will generate his/her private and public key respectively
sender.generatePrivateKey();
sender.generatePublicKey();
- After that sender will send its public key to the Internet(Unsecure Channel)
unsecureChannel.setDiffieHellmanSenderPublicKey(sender.publishPublicKey());
- Receiver will generate his/her private and public key respectively and also send his/her public key to the Internet(Unsecure Channel)
receiver.generatePrivateKey();
receiver.generatePublicKey();
unsecureChannel.setDiffieHellmanReceiverPublicKey(receiver.publishPublicKey());
- An this steps, Diffie-Hellman key exchange is done. Because both parties can generate common secret key. For example, sender can generate the common secret via:
unsecureChannel.getDiffieHellmanReceiverPublicKey(); // receiver will get the sender public key A
unsecureChannel.getPrimeNum_p(); // sender will get the prime number(p)
unsecureChannel.getAnyNum_alpha(); // sender will get the alpha number(a)
// then sender will do: A^b mod p (where b is the sender private key)
// this step is done in the encrpytFile_publish() method
- After that, sender will encrypt the files(one-page-length, ten-page-length, hundred-page-length, thousand-page-length) and publish it
sender.encryptFile_publish(unsecureChannel.getDiffieHellmanReceiverPublicKey(), i); // where i is the array index which represents the file types (i = 1 => one-page-length file, i = 10 => ten-page length file ...)
- At the same time, I am going to measure the performance of encryption & decryption process via
performanceMeasurement
instance
In this stage, sender & receiver will generate their own RSA public-private key pairs. Then according to the RSA implementation, they will encrypt/decrypt the files Measure the performance of encryption/decryption process
In this stage, we were not allowed to use any RSA implementation libraries. Then, I had to create new class.
- BigNumberGenerator to generate big prime integers p & q
Even technically possible, RSA is not an appropriate choice for big files encryption/decryption. Because:
- RSA encrypts "messages" of limited size
- RSA is a slower algorithm for big file sizes
Then I came up with the solution called Hybrid model:
- Using asymmetric and symmetric encryption/decryption.
- One of the problem in symmetric encryption is to sharing the key.
- To solve that problem, I used the RSA algorithm.
In hybrid encryption:
- Sender will generate random DES key
- Sender will encrypt the files with that DES key.
- Then sender will encrypt the DES key with RSA(via Receiver's public key) and publish to unsecure channel (Internet)
- Receiver will decrypt the encrypted DES key with its private key.
- Then receiver will be able to decrypt the files.
- Create a unsecure channel which represents the Internet
RSAUnsecureChannel unsecureChannel = new UnsecureChannel();
- Create RSAEncryption and DESEncryption (implemented in the first stage)
RSAEncryption rsaEncryption = new RSAEncryption();
DESEncryption desEncryption = new DESEncryption();
- Create a sender person
Person sender = new Sender();
- Set the RSA bit length
sender.setBitLength(BIT_LENGTH);
- Generate large prime number p & q
sender.generateLargePrimeNumber_p();
sender.generateLargePrimeNumber_q();
- Compute number N = p*q
sender.compute_number_n();
- Compute Euler's phi function T = (p-1)*(q-1)
sender.computeEulerPhiFunction();
- Compute public and private key
sender.computePublicKey();
sender.computePrivateKey();
- Generate random DES key to encrypt the files
sender.generateRandomDESKey();
Apply the same processes to the receiver instance (Person receiver = new Receiver()
)
After that, receiver will publish his/her public key to the Internet
unsecureChannel.setReceiverPublicKeyPair(receiver.getPublicKeyPair());
Right now, sender will get this pair(receiver's public key). (therefore receiver will have shared its public key with sender) from the unsecure channel to encrypt his/her random DES key
sender.encryptRandomDESKeyWithRSA(unsecureChannel.getReceiverPublicKey(), rsaEncryption); // sender encrpyts the DES key with Receiver's public key
After encrypting DES key, sender will now publish the encrypted DES key to Internet
unsecureChannel.setSenderRandomDESWithRSAEncryption(sender.getRandomDESKeyWithRSAEncryption());
Then sender will publish his/her public key to Internet
unsecureChannel.setSenderPublicKeyPair(sender.getPublicKeyPair());
After all, now sender can encrypt the files and publish them:
sender.encryptFile_publish(i, desEncryption);// where i represents the file's type
Then receiver can decrypt the files:
receiver.decryptFile(i, rsaEncryption, unsecureChannel.getSenderRandomDESWithRSAEncryption(), desEncryption);
- In this stage, sender will sign the message with his/her private key. That's means only one who has the sender's public key can verify the message. Therefore receiver can be sure about the sender. Because not other fake keys will not work.
- In this stage, integrity can be applied via hash function. Because hash function is one-way property function and output of hash function will be unique for the message. Therefore, if any bit changes in the message, hash function output will be different, then we can say that "sender's message is changed during the transmission"
- In DSA algorithm, we create signature with sender's private key. That's means only one who has the sender's public key can verify the message. Therefore we can be sure that this message belongs to the sender not attacker or something else. Thus, sender can not deny the creation of the message.
- To satisfy secrecy, I used encryption algorithm. Because of large data, I decided to use my DES implementation.
- However there is key exchange problem in DES. To solve that issue, I used my RSA implementation.
- In other words, I used hybrid encryption where key exchange was done by RSA, and encryption of the data was done by DES