---
# System prepended metadata

title: CryptoWallet to Encrypt Files
tags: [Bloom Week1]

---

# 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')
    ```