From f5c73a6f26de7af6e9598308f546b0829c743302 Mon Sep 17 00:00:00 2001 From: Harshil Darji Date: Tue, 6 Sep 2016 17:53:48 +0530 Subject: [PATCH] initial --- {other => ciphers}/rabin_miller.py | 0 ciphers/rsa_cipher.py | 124 +++++++++++++++++++++++++++++ ciphers/rsa_key_generator.py | 45 +++++++++++ 3 files changed, 169 insertions(+) rename {other => ciphers}/rabin_miller.py (100%) create mode 100644 ciphers/rsa_cipher.py create mode 100644 ciphers/rsa_key_generator.py diff --git a/other/rabin_miller.py b/ciphers/rabin_miller.py similarity index 100% rename from other/rabin_miller.py rename to ciphers/rabin_miller.py diff --git a/ciphers/rsa_cipher.py b/ciphers/rsa_cipher.py new file mode 100644 index 000000000..7e2dc5fd1 --- /dev/null +++ b/ciphers/rsa_cipher.py @@ -0,0 +1,124 @@ +import sys, rsa_key_generator as rkg, os + +DEFAULT_BLOCK_SIZE = 128 +BYTE_SIZE = 256 + +def main(): + filename = 'encrypted_file.txt' + response = input('Encrypte\Decrypt [e\d]: ') + + if response.lower().startswith('e'): + mode = 'encrypt' + elif response.lower().startswith('d'): + mode = 'decrypt' + + if mode == 'encrypt': + if not os.path.exists('rsa_pubkey.txt'): + rkg.makeKeyFiles('rsa', 1024) + + message = input('\nEnter message: ') + pubKeyFilename = 'rsa_pubkey.txt' + print('Encrypting and writing to %s...' % (filename)) + encryptedText = encryptAndWriteToFile(filename, pubKeyFilename, message) + + print('\nEncrypted text:') + print(encryptedText) + + elif mode == 'decrypt': + privKeyFilename = 'rsa_privkey.txt' + print('Reading from %s and decrypting...' % (filename)) + decryptedText = readFromFileAndDecrypt(filename, privKeyFilename) + print('writing decryption to rsa_decryption.txt...') + with open('rsa_decryption.txt', 'w') as dec: + dec.write(decryptedText) + + print('\nDecryption:') + print(decryptedText) + + +def getBlocksFromText(message, blockSize=DEFAULT_BLOCK_SIZE): + messageBytes = message.encode('ascii') + + blockInts = [] + for blockStart in range(0, len(messageBytes), blockSize): + blockInt = 0 + for i in range(blockStart, min(blockStart + blockSize, len(messageBytes))): + blockInt += messageBytes[i] * (BYTE_SIZE ** (i % blockSize)) + blockInts.append(blockInt) + return blockInts + + +def getTextFromBlocks(blockInts, messageLength, blockSize=DEFAULT_BLOCK_SIZE): + message = [] + for blockInt in blockInts: + blockMessage = [] + for i in range(blockSize - 1, -1, -1): + if len(message) + i < messageLength: + asciiNumber = blockInt // (BYTE_SIZE ** i) + blockInt = blockInt % (BYTE_SIZE ** i) + blockMessage.insert(0, chr(asciiNumber)) + message.extend(blockMessage) + return ''.join(message) + + +def encryptMessage(message, key, blockSize=DEFAULT_BLOCK_SIZE): + encryptedBlocks = [] + n, e = key + + for block in getBlocksFromText(message, blockSize): + encryptedBlocks.append(pow(block, e, n)) + return encryptedBlocks + + +def decryptMessage(encryptedBlocks, messageLength, key, blockSize=DEFAULT_BLOCK_SIZE): + decryptedBlocks = [] + n, d = key + for block in encryptedBlocks: + decryptedBlocks.append(pow(block, d, n)) + return getTextFromBlocks(decryptedBlocks, messageLength, blockSize) + + +def readKeyFile(keyFilename): + fo = open(keyFilename) + content = fo.read() + fo.close() + keySize, n, EorD = content.split(',') + return (int(keySize), int(n), int(EorD)) + + +def encryptAndWriteToFile(messageFilename, keyFilename, message, blockSize=DEFAULT_BLOCK_SIZE): + keySize, n, e = readKeyFile(keyFilename) + if keySize < blockSize * 8: + sys.exit('ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or greater than the key size. Either decrease the block size or use different keys.' % (blockSize * 8, keySize)) + + encryptedBlocks = encryptMessage(message, (n, e), blockSize) + + for i in range(len(encryptedBlocks)): + encryptedBlocks[i] = str(encryptedBlocks[i]) + encryptedContent = ','.join(encryptedBlocks) + encryptedContent = '%s_%s_%s' % (len(message), blockSize, encryptedContent) + fo = open(messageFilename, 'w') + fo.write(encryptedContent) + fo.close() + return encryptedContent + + +def readFromFileAndDecrypt(messageFilename, keyFilename): + keySize, n, d = readKeyFile(keyFilename) + fo = open(messageFilename) + content = fo.read() + messageLength, blockSize, encryptedMessage = content.split('_') + messageLength = int(messageLength) + blockSize = int(blockSize) + + if keySize < blockSize * 8: + sys.exit('ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or greater than the key size. Did you specify the correct key file and encrypted file?' % (blockSize * 8, keySize)) + + encryptedBlocks = [] + for block in encryptedMessage.split(','): + encryptedBlocks.append(int(block)) + + return decryptMessage(encryptedBlocks, messageLength, (n, d), blockSize) + +if __name__ == '__main__': + main() diff --git a/ciphers/rsa_key_generator.py b/ciphers/rsa_key_generator.py new file mode 100644 index 000000000..7cd7163b6 --- /dev/null +++ b/ciphers/rsa_key_generator.py @@ -0,0 +1,45 @@ +import random, sys, os +import rabin_miller as rabinMiller, cryptomath_module as cryptoMath + +def main(): + print('Making key files...') + makeKeyFiles('rsa', 1024) + print('Key files generation successful.') + +def generateKey(keySize): + print('Generating prime p...') + p = rabinMiller.generateLargePrime(keySize) + print('Generating prime q...') + q = rabinMiller.generateLargePrime(keySize) + n = p * q + + 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 + + print('Calculating d that is mod inverse of e...') + d = cryptoMath.findModInverse(e, (p - 1) * (q - 1)) + + publicKey = (n, e) + privateKey = (n, d) + return (publicKey, privateKey) + +def makeKeyFiles(name, keySize): + if os.path.exists('%s_pubkey.txt' % (name)) or os.path.exists('%s_privkey.txt' % (name)): + print('\nWARNING:') + print('"%s_pubkey.txt" or "%s_privkey.txt" already exists. \nUse a different name or delete these files and re-run this program.' % (name, name)) + sys.exit() + + publicKey, privateKey = generateKey(keySize) + print('\nWriting public key to file %s_pubkey.txt...' % name) + with open('%s_pubkey.txt' % name, 'w') as fo: + fo.write('%s,%s,%s' % (keySize, publicKey[0], publicKey[1])) + + print('Writing private key to file %s_privkey.txt...' % name) + with open('%s_privkey.txt' % name, 'w') as fo: + fo.write('%s,%s,%s' % (keySize, privateKey[0], privateKey[1])) + +if __name__ == '__main__': + main()