forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4569955
commit f5c73a6
Showing
3 changed files
with
169 additions
and
0 deletions.
There are no files selected for viewing
File renamed without changes.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |