Last active
August 29, 2015 14:04
-
-
Save ianjuma/e7e19fd75a9574a8a7e5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python | |
## Encryption and decryption using AES algorithm | |
## with a salting function | |
## two-one way functions defined - encrypt() / decrypt() | |
import hashlib | |
import random, os | |
import base64 | |
from Crypto.Cipher import AES | |
# random salt generator | |
salt = os.urandom(24) | |
cipher = AES.new(salt, AES.MODE_CBC) | |
def encrypt(message): | |
""" | |
func to receive a message encrypt and store in a file, for reading | |
""" | |
encryptedMessage = hashlib.sha512(message + salt).hexdigest() | |
encoded = base64.b64encode(cipher.encrypt(message)) | |
return encoded | |
def decrypt(encryptedMessage): | |
""" | |
func to decrypt a message and store in a file | |
""" | |
message = cipher.decrypt(base64.b64decode(encryptedMessage)) | |
return message | |
x = encrypt("go home") | |
print x | |
y = decrypt(x) | |
print y | |
""" | |
The ideal cryptographic hash function has four main properties: | |
1. it is easy to compute the hash value for any given message | |
2. it is infeasible to generate a message that has a given hash | |
3. it is infeasible to modify a message without changing the hash | |
4. it is infeasible to find two different messages with the same hash. | |
""" | |
# Program 2 | |
================================================================================== | |
================================================================================== | |
import os | |
import hashlib | |
import Crypto.Cipher.AES as AES | |
class Cipher: | |
@staticmethod | |
def md5sum(raw): | |
m = hashlib.md5() | |
m.update(raw) | |
return m.hexdigest() | |
BS = AES.block_size | |
@staticmethod | |
def pad(s): | |
"""note that the padding is no necessary""" | |
"""return s + (Cipher.BS - len(s) % Cipher.BS) * chr(Cipher.BS - len(s) % Cipher.BS)""" | |
return s | |
@staticmethod | |
def unpad(s): | |
"""return s[0:-ord(s[-1])]""" | |
return s | |
def __init__(self, key): | |
self.key = Cipher.md5sum(key) | |
#the state of the counter callback | |
self.cnter_cb_called = 0 | |
self.secret = None | |
def _reset_counter_callback_state(self, secret): | |
self.cnter_cb_called = 0 | |
self.secret = secret | |
def _counter_callback(self): | |
""" | |
this function should be stateful | |
""" | |
self.cnter_cb_called += 1 | |
return self.secret[self.cnter_cb_called % Cipher.BS] * Cipher.BS | |
def encrypt(self, raw): | |
secret = os.urandom( | |
Cipher.BS) # random choose a "secret" which is not secret | |
self._reset_counter_callback_state(secret) | |
cipher = AES.new(self.key, AES.MODE_CTR, | |
counter=self._counter_callback) | |
raw_padded = Cipher.pad(raw) | |
enc_padded = cipher.encrypt(raw_padded) | |
return secret + enc_padded # yes, it is not secret | |
def decrypt(self, enc): | |
secret = enc[:Cipher.BS] | |
self._reset_counter_callback_state(secret) | |
cipher = AES.new(self.key, AES.MODE_CTR, | |
counter=self._counter_callback) | |
enc_padded = enc[Cipher.BS:] | |
#we didn't encrypt the secret, so don't decrypt it | |
raw_padded = cipher.decrypt(enc_padded) | |
return Cipher.unpad(raw_padded) | |
from Cipher import Cipher | |
x = Cipher("this is key") | |
"a"==x.decrypt(x.encrypt("a")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment