forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rsa_cipher.py
124 lines (94 loc) · 4.3 KB
/
rsa_cipher.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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()