Discuss Cryptography with Python ”; Previous Next Modern cryptography is the one used widely among computer science projects to secure the data messages. This tutorial covers the basic concepts of cryptography and its implementation in Python scripting language. After completing this tutorial, you will be able to relate the basic techniques of cryptography in real world scenarios Print Page Previous Next Advertisements ”;
Category: cryptography With Python
Understanding RSA Algorithm
Understanding RSA Algorithm ”; Previous Next RSA algorithm is a public key encryption technique and is considered as the most secure way of encryption. It was invented by Rivest, Shamir and Adleman in year 1978 and hence name RSA algorithm. Algorithm The RSA algorithm holds the following features − RSA algorithm is a popular exponentiation in a finite field over integers including prime numbers. The integers used by this method are sufficiently large making it difficult to solve. There are two sets of keys in this algorithm: private key and public key. You will have to go through the following steps to work on RSA algorithm − Step 1: Generate the RSA modulus The initial procedure begins with selection of two prime numbers namely p and q, and then calculating their product N, as shown − N=p*q Here, let N be the specified large number. Step 2: Derived Number (e) Consider number e as a derived number which should be greater than 1 and less than (p-1) and (q-1). The primary condition will be that there should be no common factor of (p-1) and (q-1) except 1 Step 3: Public key The specified pair of numbers n and e forms the RSA public key and it is made public. Step 4: Private Key Private Key d is calculated from the numbers p, q and e. The mathematical relationship between the numbers is as follows − ed = 1 mod (p-1) (q-1) The above formula is the basic formula for Extended Euclidean Algorithm, which takes p and q as the input parameters. Encryption Formula Consider a sender who sends the plain text message to someone whose public key is (n,e). To encrypt the plain text message in the given scenario, use the following syntax − C = Pe mod n Decryption Formula The decryption process is very straightforward and includes analytics for calculation in a systematic approach. Considering receiver C has the private key d, the result modulus will be calculated as − Plaintext = Cd mod n Print Page Previous Next Advertisements ”;
Decryption of Simple Substitution Cipher ”; Previous Next In this chapter, you can learn about simple implementation of substitution cipher which displays the encrypted and decrypted message as per the logic used in simple substitution cipher technique. This can be considered as an alternative approach of coding. Code You can use the following code to perform decryption using simple substitution cipher − import random chars = ”ABCDEFGHIJKLMNOPQRSTUVWXYZ” + ”abcdefghijklmnopqrstuvwxyz” + ”0123456789” + ”:.;,?!@#$%&()+=-*/_ []{}`~^””\” def generate_key(): “””Generate an key for our cipher””” shuffled = sorted(chars, key=lambda k: random.random()) return dict(zip(chars, shuffled)) def encrypt(key, plaintext): “””Encrypt the string and return the ciphertext””” return ””.join(key[l] for l in plaintext) def decrypt(key, ciphertext): “””Decrypt the string and return the plaintext””” flipped = {v: k for k, v in key.items()} return ””.join(flipped[l] for l in ciphertext) def show_result(plaintext): “””Generate a resulting cipher with elements shown””” key = generate_key() encrypted = encrypt(key, plaintext) decrypted = decrypt(key, encrypted) print ”Key: %s” % key print ”Plaintext: %s” % plaintext print ”Encrypted: %s” % encrypted print ”Decrypted: %s” % decrypted show_result(”Hello World. This is demo of substitution cipher”) Output The above code gives you the output as shown here − Print Page Previous Next Advertisements ”;
RSA Cipher Encryption
RSA Cipher Encryption ”; Previous Next In this chapter, we will focus on different implementation of RSA cipher encryption and the functions involved for the same. You can refer or include this python file for implementing RSA cipher algorithm implementation. The modules included for the encryption algorithm are as follows − from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5 from Crypto import Random from base64 import b64encode, b64decode hash = “SHA-256” We have initialized the hash value as SHA-256 for better security purpose. We will use a function to generate new keys or a pair of public and private key using the following code. def newkeys(keysize): random_generator = Random.new().read key = RSA.generate(keysize, random_generator) private, public = key, key.publickey() return public, private def importKey(externKey): return RSA.importKey(externKey) For encryption, the following function is used which follows the RSA algorithm − def encrypt(message, pub_key): cipher = PKCS1_OAEP.new(pub_key) return cipher.encrypt(message) Two parameters are mandatory: message and pub_key which refers to Public key. A public key is used for encryption and private key is used for decryption. The complete program for encryption procedure is mentioned below − from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5 from Crypto import Random from base64 import b64encode, b64decode hash = “SHA-256″ def newkeys(keysize): random_generator = Random.new().read key = RSA.generate(keysize, random_generator) private, public = key, key.publickey() return public, private def importKey(externKey): return RSA.importKey(externKey) def getpublickey(priv_key): return priv_key.publickey() def encrypt(message, pub_key): cipher = PKCS1_OAEP.new(pub_key) return cipher.encrypt(message) Print Page Previous Next Advertisements ”;
Affine Ciphers
Cryptography with Python – Affine Cipher ”; Previous Next Affine Cipher is the combination of Multiplicative Cipher and Caesar Cipher algorithm. The basic implementation of affine cipher is as shown in the image below − In this chapter, we will implement affine cipher by creating its corresponding class that includes two basic functions for encryption and decryption. Code You can use the following code to implement an affine cipher − class Affine(object): DIE = 128 KEY = (7, 3, 55) def __init__(self): pass def encryptChar(self, char): K1, K2, kI = self.KEY return chr((K1 * ord(char) + K2) % self.DIE) def encrypt(self, string): return “”.join(map(self.encryptChar, string)) def decryptChar(self, char): K1, K2, KI = self.KEY return chr(KI * (ord(char) – K2) % self.DIE) def decrypt(self, string): return “”.join(map(self.decryptChar, string)) affine = Affine() print affine.encrypt(”Affine Cipher”) print affine.decrypt(”*18?FMT”) Output You can observe the following output when you implement an affine cipher − The output displays the encrypted message for the plain text message Affine Cipher and decrypted message for the message sent as input abcdefg. Print Page Previous Next Advertisements ”;
Creating RSA Keys
Creating RSA Keys ”; Previous Next In this chapter, we will focus on step wise implementation of RSA algorithm using Python. Generating RSA keys The following steps are involved in generating RSA keys − Create two large prime numbers namely p and q. The product of these numbers will be called n, where n= p*q Generate a random number which is relatively prime with (p-1) and (q-1). Let the number be called as e. Calculate the modular inverse of e. The calculated inverse will be called as d. Algorithms for generating RSA keys We need two primary algorithms for generating RSA keys using Python − Cryptomath module and Rabin Miller module. Cryptomath Module The source code of cryptomath module which follows all the basic implementation of RSA algorithm is as follows − def gcd(a, b): while a != 0: a, b = b % a, a return b def findModInverse(a, m): if gcd(a, m) != 1: return None u1, u2, u3 = 1, 0, a v1, v2, v3 = 0, 1, m while v3 != 0: q = u3 // v3 v1, v2, v3, u1, u2, u3 = (u1 – q * v1), (u2 – q * v2), (u3 – q * v3), v1, v2, v3 return u1 % m RabinMiller Module The source code of RabinMiller module which follows all the basic implementation of RSA algorithm is as follows − import random def rabinMiller(num): s = num – 1 t = 0 while s % 2 == 0: s = s // 2 t += 1 for trials in range(5): a = random.randrange(2, num – 1) v = pow(a, s, num) if v != 1: i = 0 while v != (num – 1): if i == t – 1: return False else: i = i + 1 v = (v ** 2) % num return True def isPrime(num): if (num 7< 2): return False lowPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997] if num in lowPrimes: return True for prime in lowPrimes: if (num % prime == 0): return False return rabinMiller(num) def generateLargePrime(keysize = 1024): while True: num = random.randrange(2**(keysize-1), 2**(keysize)) if isPrime(num): return num The complete code for generating RSA keys is as follows − import random, sys, os, rabinMiller, cryptomath def main(): makeKeyFiles(”RSA_demo”, 1024) def generateKey(keySize): # Step 1: Create two prime numbers, p and q. Calculate n = p * q. print(”Generating p prime…”) p = rabinMiller.generateLargePrime(keySize) print(”Generating q prime…”) q = rabinMiller.generateLargePrime(keySize) n = p * q # Step 2: Create a number e that is relatively prime to (p-1)*(q-1). print(”Generating e that is relatively prime to (p-1)*(q-1)…”) while True: e = random.randrange(2 ** (keySize – 1), 2 ** (keySize)) if cryptomath.gcd(e, (p – 1) * (q – 1)) == 1: break # Step 3: Calculate d, the mod inverse of e. print(”Calculating d that is mod inverse of e…”) d = cryptomath.findModInverse(e, (p – 1) * (q – 1)) publicKey = (n, e) privateKey = (n, d) print(”Public key:”, publicKey) print(”Private key:”, privateKey) return (publicKey, privateKey) def makeKeyFiles(name, keySize): # Creates two files ”x_pubkey.txt” and ”x_privkey.txt” (where x is the value in name) with the the n,e and d,e integers written in them, # delimited by a comma. if os.path.exists(”%s_pubkey.txt” % (name)) or os.path.exists(”%s_privkey.txt” % (name)): sys.exit(”WARNING: The file %s_pubkey.txt or %s_privkey.txt already exists! Use a different name or delete these files and re-run this program.” % (name, name)) publicKey, privateKey = generateKey(keySize) print() print(”The public key is a %s and a %s digit number.” % (len(str(publicKey[0])), len(str(publicKey[1])))) print(”Writing public key to file %s_pubkey.txt…” % (name)) fo = open(”%s_pubkey.txt” % (name), ”w”) fo.write(”%s,%s,%s” % (keySize, publicKey[0], publicKey[1])) fo.close() print() print(”The private key is a %s and a %s digit number.” % (len(str(publicKey[0])), len(str(publicKey[1])))) print(”Writing private key to file %s_privkey.txt…” % (name)) fo = open(”%s_privkey.txt” % (name), ”w”) fo.write(”%s,%s,%s” % (keySize, privateKey[0], privateKey[1])) fo.close() # If makeRsaKeys.py is run (instead of imported as a module) call # the main() function. if __name__ == ”__main__”: main() Output The public key and private keys are generated and saved in the respective files as shown in the following output. Print Page Previous Next Advertisements ”;
RSA Cipher Decryption
RSA Cipher Decryption ”; Previous Next This chapter is a continuation of the previous chapter where we followed step wise implementation of encryption using RSA algorithm and discusses in detail about it. The function used to decrypt cipher text is as follows − def decrypt(ciphertext, priv_key): cipher = PKCS1_OAEP.new(priv_key) return cipher.decrypt(ciphertext) For public key cryptography or asymmetric key cryptography, it is important to maintain two important features namely Authentication and Authorization. Authorization Authorization is the process to confirm that the sender is the only one who have transmitted the message. The following code explains this − def sign(message, priv_key, hashAlg=”SHA-256″): global hash hash = hashAlg signer = PKCS1_v1_5.new(priv_key) if (hash == “SHA-512”): digest = SHA512.new() elif (hash == “SHA-384”): digest = SHA384.new() elif (hash == “SHA-256”): digest = SHA256.new() elif (hash == “SHA-1”): digest = SHA.new() else: digest = MD5.new() digest.update(message) return signer.sign(digest) Authentication Authentication is possible by verification method which is explained as below − def verify(message, signature, pub_key): signer = PKCS1_v1_5.new(pub_key) if (hash == “SHA-512”): digest = SHA512.new() elif (hash == “SHA-384”): digest = SHA384.new() elif (hash == “SHA-256”): digest = SHA256.new() elif (hash == “SHA-1”): digest = SHA.new() else: digest = MD5.new() digest.update(message) return signer.verify(digest, signature) The digital signature is verified along with the details of sender and recipient. This adds more weight age for security purposes. RSA Cipher Decryption You can use the following code for RSA cipher decryption − from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5 from Crypto import Random from base64 import b64encode, b64decode hash = “SHA-256” def newkeys(keysize): random_generator = Random.new().read key = RSA.generate(keysize, random_generator) private, public = key, key.publickey() return public, private def importKey(externKey): return RSA.importKey(externKey) def getpublickey(priv_key): return priv_key.publickey() def encrypt(message, pub_key): cipher = PKCS1_OAEP.new(pub_key) return cipher.encrypt(message) def decrypt(ciphertext, priv_key): cipher = PKCS1_OAEP.new(priv_key) return cipher.decrypt(ciphertext) def sign(message, priv_key, hashAlg = “SHA-256”): global hash hash = hashAlg signer = PKCS1_v1_5.new(priv_key) if (hash == “SHA-512”): digest = SHA512.new() elif (hash == “SHA-384”): digest = SHA384.new() elif (hash == “SHA-256”): digest = SHA256.new() elif (hash == “SHA-1”): digest = SHA.new() else: digest = MD5.new() digest.update(message) return signer.sign(digest) def verify(message, signature, pub_key): signer = PKCS1_v1_5.new(pub_key) if (hash == “SHA-512”): digest = SHA512.new() elif (hash == “SHA-384”): digest = SHA384.new() elif (hash == “SHA-256”): digest = SHA256.new() elif (hash == “SHA-1″): digest = SHA.new() else: digest = MD5.new() digest.update(message) return signer.verify(digest, signature) Print Page Previous Next Advertisements ”;
Python Modules of Cryptography ”; Previous Next In this chapter, you will learn in detail about various modules of cryptography in Python. Cryptography Module It includes all the recipes and primitives, and provides a high level interface of coding in Python. You can install cryptography module using the following command − pip install cryptography Code You can use the following code to implement the cryptography module − from cryptography.fernet import Fernet key = Fernet.generate_key() cipher_suite = Fernet(key) cipher_text = cipher_suite.encrypt(“This example is used to demonstrate cryptography module”) plain_text = cipher_suite.decrypt(cipher_text) Output The code given above produces the following output − The code given here is used to verify the password and creating its hash. It also includes logic for verifying the password for authentication purpose. import uuid import hashlib def hash_password(password): # uuid is used to generate a random number of the specified password salt = uuid.uuid4().hex return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ”:” + salt def check_password(hashed_password, user_password): password, salt = hashed_password.split(”:”) return password == hashlib.sha256(salt.encode() + user_password.encode()).hexdigest() new_pass = input(”Please enter a password: ”) hashed_password = hash_password(new_pass) print(”The string to store in the db is: ” + hashed_password) old_pass = input(”Now please enter the password again to check: ”) if check_password(hashed_password, old_pass): print(”You entered the right password”) else: print(”Passwords do not match”) Output Scenario 1 − If you have entered a correct password, you can find the following output − Scenario 2 − If we enter wrong password, you can find the following output − Explanation Hashlib package is used for storing passwords in a database. In this program, salt is used which adds a random sequence to the password string before implementing the hash function. Print Page Previous Next Advertisements ”;
Symmetric and Asymmetric Cryptography ”; Previous Next In this chapter, let us discuss in detail about symmetric and asymmetric cryptography. Symmetric Cryptography In this type, the encryption and decryption process uses the same key. It is also called as secret key cryptography. The main features of symmetric cryptography are as follows − It is simpler and faster. The two parties exchange the key in a secure way. Drawback The major drawback of symmetric cryptography is that if the key is leaked to the intruder, the message can be easily changed and this is considered as a risk factor. Data Encryption Standard (DES) The most popular symmetric key algorithm is Data Encryption Standard (DES) and Python includes a package which includes the logic behind DES algorithm. Installation The command for installation of DES package pyDES in Python is − pip install pyDES Simple program implementation of DES algorithm is as follows − import pyDes data = “DES Algorithm Implementation” k = pyDes.des(“DESCRYPT”, pyDes.CBC, “”, pad=None, padmode=pyDes.PAD_PKCS5) d = k.encrypt(data) print “Encrypted: %r” % d print “Decrypted: %r” % k.decrypt(d) assert k.decrypt(d) == data It calls for the variable padmode which fetches all the packages as per DES algorithm implementation and follows encryption and decryption in a specified manner. Output You can see the following output as a result of the code given above − Asymmetric Cryptography It is also called as public key cryptography. It works in the reverse way of symmetric cryptography. This implies that it requires two keys: one for encryption and other for decryption. The public key is used for encrypting and the private key is used for decrypting. Drawback Due to its key length, it contributes lower encryption speed. Key management is crucial. The following program code in Python illustrates the working of asymmetric cryptography using RSA algorithm and its implementation − from Crypto import Random from Crypto.PublicKey import RSA import base64 def generate_keys(): # key length must be a multiple of 256 and >= 1024 modulus_length = 256*4 privatekey = RSA.generate(modulus_length, Random.new().read) publickey = privatekey.publickey() return privatekey, publickey def encrypt_message(a_message , publickey): encrypted_msg = publickey.encrypt(a_message, 32)[0] encoded_encrypted_msg = base64.b64encode(encrypted_msg) return encoded_encrypted_msg def decrypt_message(encoded_encrypted_msg, privatekey): decoded_encrypted_msg = base64.b64decode(encoded_encrypted_msg) decoded_decrypted_msg = privatekey.decrypt(decoded_encrypted_msg) return decoded_decrypted_msg a_message = “This is the illustration of RSA algorithm of asymmetric cryptography” privatekey , publickey = generate_keys() encrypted_msg = encrypt_message(a_message , publickey) decrypted_msg = decrypt_message(encrypted_msg, privatekey) print “%s – (%d)” % (privatekey.exportKey() , len(privatekey.exportKey())) print “%s – (%d)” % (publickey.exportKey() , len(publickey.exportKey())) print ” Original content: %s – (%d)” % (a_message, len(a_message)) print “Encrypted message: %s – (%d)” % (encrypted_msg, len(encrypted_msg)) print “Decrypted message: %s – (%d)” % (decrypted_msg, len(decrypted_msg)) Output You can find the following output when you execute the code given above − Print Page Previous Next Advertisements ”;
Hacking RSA Cipher
Hacking RSA Cipher ”; Previous Next Hacking RSA cipher is possible with small prime numbers, but it is considered impossible if it is used with large numbers. The reasons which specify why it is difficult to hack RSA cipher are as follows − Brute force attack would not work as there are too many possible keys to work through. Also, this consumes a lot of time. Dictionary attack will not work in RSA algorithm as the keys are numeric and does not include any characters in it. Frequency analysis of the characters is very difficult to follow as a single encrypted block represents various characters. There are no specific mathematical tricks to hack RSA cipher. The RSA decryption equation is − M = C^d mod n With the help of small prime numbers, we can try hacking RSA cipher and the sample code for the same is mentioned below − def p_and_q(n): data = [] for i in range(2, n): if n % i == 0: data.append(i) return tuple(data) def euler(p, q): return (p – 1) * (q – 1) def private_index(e, euler_v): for i in range(2, euler_v): if i * e % euler_v == 1: return i def decipher(d, n, c): return c ** d % n def main(): e = int(input(“input e: “)) n = int(input(“input n: “)) c = int(input(“input c: “)) # t = 123 # private key = (103, 143) p_and_q_v = p_and_q(n) # print(“[p_and_q]: “, p_and_q_v) euler_v = euler(p_and_q_v[0], p_and_q_v[1]) # print(“[euler]: “, euler_v) d = private_index(e, euler_v) plain = decipher(d, n, c) print(“plain: “, plain) if __name__ == “__main__”: main() Output The above code produces the following output − Print Page Previous Next Advertisements ”;