# CryptoWallet to Encrypt Files ###### tags: `Bloom Week1` ## :scroll: GitHub Repo for the Project ➜ [PyCryption](https://github.com/ShivaShanmuganathan/PyCryption) ## :mag: How does it work? ## :camera: UML diagrams ### Shan wants to send a `message` to Shiva ```sequence Shan->Shiva: Request for Shiva's Public Key Shiva-->Shan: Sends Public Key Note left of Shan: Encrypts message Note left of Shan: Sign encrypted message Shan->Shiva: Sends Encrypted Message Shan->Shiva: Sends Signature Shan->Shiva: Sends Public Key Note right of Shiva: Verify Sign using Public Key Note right of Shiva: Decrypt message ``` ## :book: Detailed Explaination 1. Alice requests for Bob's `public_key` 2. Alice performs `symmetric encryption` on the `message` 3. Alice encrypts the `symmetric_key` using Bob's public key 4. Alice signs the `encrypted_message` using Alice's `private_key` 5. Alice sends the `public_key` of Alice, `encrypted_message`, and `signature` to Bob 6. Bob verifies the `encrypted_message` using the signature and Alice's `public_key`. 7. Bob decryptes the `encrypted_message` using Bob's `private_key` ## :rocket: Features - [x] Perform both Symmetric & Asymmetric Encryption - [x] Signing messages - [x] Verifying signature - [x] Encrypting messages - [x] Decrypting messages - [x] Dockerized the application ## 🖭 How does each file work? ### :rocket: [create_keys.py](https://github.com/ShivaShanmuganathan/PyCryption/blob/master/create_keys.py) - Using RSA to generate Public and Private key of Receiver ``` import rsa #----------CREATING RECEIVER'S PUBLIC & PRIVATE KEYS------------# # CREATE THE PUB & PRIVATE KEYS (pubkey,privkey)=rsa.newkeys(2048) # WRITE THE PUBLIC KEY TO A FILE pukey = open('publickey.key','wb') pukey.write(pubkey.save_pkcs1('PEM')) pukey.close() # WRITE THE PRIVATE KEY TO A FILE prkey = open('privkey.key','wb') prkey.write(privkey.save_pkcs1('PEM')) prkey.close() print('PUBLIC & PRIVATE KEY OF RECEIVER HAS BEEN GENERATED') ``` --- ### :rocket: [encrypt.py](https://github.com/ShivaShanmuganathan/PyCryption/blob/master/encrypt.py) ### Alice performs encryption and signs the message - Perform `Symmetric Encryption` on the `Message` - Encrypt `Symmetric_Key` using Bob's `Public_Key` - Generate `public_key` and `private_key` for Alice - Sign the `encrypted_message` using Alice's `private_key` ### These 4 Files need to be sent to Bob ##### 1. `encrypted_symmetric_key` ##### 2. Alice's `public_key` ##### 3. `signature` ##### 4. `encrypted_message` ``` from cryptography.fernet import Fernet import rsa #----------FILE ENCRYPTION USING SYMMETRIC KEY---------------# # CREATE THE SYMMETRIC KEY AND CIPHER symKey = Fernet.generate_key() cipher = Fernet(symKey) # GET FILENAME TO ENCRYPT filename = input("Enter filename to encrypt [with extension]:\n") myfile = open(filename,'rb') myfiledata = myfile.read() # ENCRYPT THE DATA AND CREATE ENCRYTPED FILE encrypted_data = cipher.encrypt(myfiledata) edata = open('enc_' + filename ,'wb') edata.write(encrypted_data) #----------USING RECEIVER'S PUBLIC KEY TO ENCRYPT SYMMETRIC KEY------------# # OPEN AND LOAD THE PUBLIC KEY FILE OF RECEIVER pkey = open('publickey.key','rb') pkdata = pkey.read() pubkey = rsa.PublicKey.load_pkcs1(pkdata) # ENCRYPT THE SYMMETRIC KEY WITH THE PUBLIC KEY encrypted_key = rsa.encrypt(symKey,pubkey) ekey = open('encrypted_key','wb') ekey.write(encrypted_key) #----------USING SENDER'S PRIVATE KEY TO SIGN MESSAGE------------# # GENERATE ASYMMETRIC KEY PAIR [to use for signature] (public_key, private_key) = rsa.newkeys(512) vkey = open('public_verify.key','wb') vkey.write(public_key.save_pkcs1('PEM')) vkey.close() # GENERATE SIGNATURE FILE signature = rsa.sign(encrypted_data, private_key, 'SHA-1') sign = open('sign.txt','wb') sign.write(signature) sign.close() print('------- ENCRYPTION COMPLETE ---------') print('\n') print(' YOU CAN NOW SHARE THE ENCRYPTED FILE: _enc' +filename+ '\n' ); print(' YOU CAN NOW SHARE THE ENCRYPTED SYMMETRIC KEY: encrypted_key \n' ); print(' YOU CAN NOW SHARE THE PUBLIC KEY OF SENDER: public_verify.key \n' ); print(' YOU CAN NOW SHARE THE SIGNATURE: sign.txt \n' ); ``` --- ### :rocket: [decrypt.py](https://github.com/ShivaShanmuganathan/PyCryption/blob/master/decrypt.py) ### Bob performs decryption and verifies the message - Bob's `private_key` is used to decrypt the `encrypted_symmetric_key` - `symmetric_key` is used to decrypt the `Message` - `signature` is verified using Alice's `public_key` ### Bob can now access the decrypted message. ``` import rsa from cryptography.fernet import Fernet # OEPN RECEIVER'S PRIVATE KEY [to decrypt the symmetric key] prkey = open('privkey.key','rb') pkey = prkey.read() private_key = rsa.PrivateKey.load_pkcs1(pkey) # DECRYPT SYMMETRIC KEY USING RECEIVER'S PRIVATE KEY s = open('encrypted_key','rb') sym = s.read() symKey = rsa.decrypt(sym,private_key) cipher = Fernet(symKey) # DECRYPTION USING CIPHER OF SYMMETRIC KEY filename = input("Enter filename to decrypt [with extension]:\n") encrypted_data = open(filename,'rb') edata = encrypted_data.read() decrypted_data = cipher.decrypt(edata) message = decrypted_data # OPENING THE PUBLIC KEY OF SENDER AND SIGNATURE vkey = open('public_verify.key','rb') vdata = vkey.read() public_verify = rsa.PublicKey.load_pkcs1(vdata) sign = open('sign.txt','rb') signature = sign.read() # VERIFYING SIGNATURE try: rsa.verify(edata, signature, public_verify) print('signature verified') # load the file with open('decrypted_' + filename,'wb') as df: df.write(decrypted_data) print('Check----->'+ 'decrypted_'+filename+ '<------to get the decrypted file') except: print('message is tampered') ```