Generate public/private keys, encrypt, decrypt, sign, verifyEncrypt/decrypt PHP function.NET 4.5 licensing...

It took me a lot of time to make this, pls like. (YouTube Comments #1)

Isn't using the Extrusion Multiplier like cheating?

What makes the Forgotten Realms "forgotten"?

Is there a standard way to treat events with unknown times (missing time data)?

Slow moving projectiles from a hand-held weapon - how do they reach the target?

Blindfold battle as a gladiatorial spectacle - what are the tactics and communication methods?

Magento 2 : Call Helper Without Using __construct in Own Module

Can I write a book of my D&D game?

Can a person refuse a presidential pardon?

If I sold a PS4 game I owned the disc for, can I reinstall it digitally?

Why would the Pakistan airspace closure cancel flights not headed to Pakistan itself?

Is there some relative to Dutch word "kijken" in German?

How do you funnel food off a cutting board?

Lick explanation

Can a dragon be stuck looking like a human?

How to prevent users from executing commands through browser URL

Is casting an attack cantrip from a wand an "attack action made with a magic weapon"?

What is the lore-based reason that the Spectator has the Create Food and Water trait, instead of simply not requiring food and water?

Would a National Army of mercenaries be a feasible idea?

How to acknowledge an embarrassing job interview, now that I work directly with the interviewer?

Why did other German political parties disband so fast when Hitler was appointed chancellor?

Why does lambda auto& parameter choose const overload?

How should I handle players who ignore the session zero agreement?

Dilemma of explaining to interviewer that he is the reason for declining second interview



Generate public/private keys, encrypt, decrypt, sign, verify


Encrypt/decrypt PHP function.NET 4.5 licensing subsystem using RSA-4096 strong name key, SHA256 signed XML, and assembly signature enforcingAPI with security through a private and public keyGenerating public/private RSA key pair programmatically, using it for JWTsLocally encrypt/decrypt credentialsencrypt/decrypt person dataCaesar Cipher encrypt/decrypt toolEncrypt and decrypt a message using AES-256 with GCM mode using Bouncy Castle C# libraryA Public and Private Key generator for RSACounter object in Python with public and private methods













8












$begingroup$


My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk of the data for speed, and encrypts the random key with RSA. Many operations were chosen for speed. This works out of the box on 3.6+ . Windows idle env disallows it from working there, but Linux and mac is ideal. I do call gzip which I know I can replace with a module. I almost want to do my own Huffman coding for it but I don't know where to draw the line.



The RSA and DSA portions are written from number theory and don't use the modules, that was the point. I don't know how to put this in the title without it being edited it out. The RSA and DSA portions are manual implementations of the mathematics. The prime finding algorithms are implementations of two theorems, applied in an order to achieve maximum sieving speed.I did away with my lucas test as doing a large number of Miller Rabin tests produces a probability of 1 of being prime.



I'm using this as an educational tool to force the unwilling learners to kinetically understand public and private key cryptography when passed on a USB etc. in a classroom setting. To see the clicks in peoples eyes when they understand signing or the like, that's why I'm sharing this code. I know there's much better ways to handle the data concatenation, but am happy that I'm processing the data at a binary level.



I love the prime number theorem and so should you.



#!/usr/bin/env python3
import os
import sys
import math
import re
import hashlib
import random
import base64
import string
import getpass
import multiprocessing as mp
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2

#Primality testing, extended greatest common divisor and least common multiple
def isprime(n):
if not n & 1: #check if first bit is 1
return False
for i in (3,5,7,11):
if divmod(n, i)[1] == 0:
return False
#Fermat
if (pow(2, n-1, n)) != 1:
return False
#MilRab, x**2 = 1 mod P - ERH
s = 0
d = n-1
while not d & 1:
d>>=1 #shifts binary rep of number right one place, same as dividing by 2^d
s+=1
assert(2**s * d == n-1) #Process to find s and d
def trial_composite(a):
if pow(a, d, n) == 1:
return False
for i in range(s):
if pow(a, 2**i * d, n) == n-1:
return False
return True
for i in range(100):#Number of Rabin Witness
a = random.randrange(2, n-1)
if trial_composite(a):
return False
return True

def get1prime(keysize):
while True:
p = random.randrange(1<<(keysize), 1<<(keysize+2))
if isprime(p):
return p

def modInverse(a, m) : #Euclid's Extended Algorithm
m0 = m
y = 0
x = 1
while (a > 1) :
q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t
if (x < 0) :
x = x + m0
return x

def lcm(x, y):
lcm = (x*y)//math.gcd(x,y)
return lcm

##AES256CHUNK
def get_private_key(password):
salt = b"We will know, we must know"
kdf = PBKDF2(password, salt, 64, 1000)
key = kdf[:32]
return key

def encryptaes(raw, password):
private_key = password
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))

def decryptaes(enc, password):
private_key = password
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:]))

BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537

def encryptit(e, n, thestring):#for sigining pass d as e
rbinlist = ['{0:08b}'.format(x) for x in thestring]
catstring = ''
catstring += rbinlist[0].lstrip('0')
del rbinlist[0]
for i in rbinlist:
catstring += str(i)
puttynumber = int(catstring,2)
cypherstring = str(pow(puttynumber, e, n))
return cypherstring

def decryptit(d, n, cynum):#for signing pass e as d
decryptmsg = ''
n = int(n)
d = int(d)
puttynum = pow(int(cynum), d, n)
puttynum = '{0:08b}'.format(puttynum)
while True:
if len(puttynum)%8 == 0:
break
puttynum = '0{0}'.format(puttynum)
locs = re.findall('[01]{8}', puttynum)
for x in locs:
letter = chr(int(x,2))
decryptmsg += letter
return decryptmsg

#Begin User Flow
choice = input("""



Welcome to Dan's Cryptography Concept Program.
Generate/Encrypt/Decrypt/Sign
RSA++/DSA++/AES/OTP/Double DH key exch w SHA
Choose:
A: Generate New Public/Private Key Pair
B: Encrypt a File
C: Decrypt a File
=> """)

if choice == 'A' or choice == 'a':
try:
keysize = (int(input("Enter a keysize: "))>>1)
except ValueError as a:
print('Enter a numbernn')
sys.exit()
pubkeyname = input('Input desired public key name: ')
pkey = input('Input desired private key name: ')
pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
print('Generating Keys...')
primes = []
plist = []
for i in range(mp.cpu_count()):
plist.append(keysize)
workpool = mp.Pool(processes=mp.cpu_count())
reslist = workpool.imap_unordered(get1prime, plist)
workpool.close()
for res in reslist:
if res:
primes.append(res)
workpool.terminate()
break
workpool.join()
#
workpool1 = mp.Pool(processes=mp.cpu_count())
reslist = workpool1.imap_unordered(get1prime, plist)
workpool1.close()
for res in reslist:
if res:
primes.append(res)
workpool1.terminate()
break
workpool1.join()
if primes[0] != primes[1]:
p, q = primes[0], primes[1]
else:
print('Supremely Unlucky Try Again')
exit()
n = p*q
cm = lcm(p-1, q-1)
print('Computing Private key ...')
d = modInverse(e, cm)
print('Private Key Size: {} bits'.format(keysize*2))
print('Functional Length of: {}'.format(len(bin((d)))))
keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
with open(pkey, 'w') as f1:
f1.write(str(n)+'n')
f1.write(bytes.decode(keystring))
with open(pubkeyname, 'w') as f2:
f2.write(b64key)
print('Complete - {} and {} generated'.format(pubkeyname,pkey))
print('e exponent: {}'.format(str(e)))
print("""
-----BEGIN PUBLIC KEY-----
{}-----END PUBLIC KEY-----
""".format(b64key))
b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
print("""
-----BEGIN PRIVATE KEY-----
{}-----END PRIVATE KEY-----
""".format(b64privkey))

if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
print('Wrote out to {} '.format(outfile))









share|improve this question









New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$








  • 2




    $begingroup$
    If you have at least one space before the #, the syntax highlighter does not get confused by ' in the comments.
    $endgroup$
    – Graipher
    2 days ago










  • $begingroup$
    To be clear: as this is a teaching aid rather than a practical tool, you're not interested in resistance to information leakage through observation of timing and power consumption, right?
    $endgroup$
    – Toby Speight
    2 days ago










  • $begingroup$
    Well, I'd be interested. The tools is used so students can pass and sign data with public and private keys, just using the program. The internals are my research. I'm extremely curious to know how observing the timing and power could be used to glean meaningful information from either the key generation or encryption.
    $endgroup$
    – dhoyt902
    2 days ago










  • $begingroup$
    Thank you Graipher
    $endgroup$
    – dhoyt902
    2 days ago






  • 1




    $begingroup$
    Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    $endgroup$
    – Mast
    yesterday
















8












$begingroup$


My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk of the data for speed, and encrypts the random key with RSA. Many operations were chosen for speed. This works out of the box on 3.6+ . Windows idle env disallows it from working there, but Linux and mac is ideal. I do call gzip which I know I can replace with a module. I almost want to do my own Huffman coding for it but I don't know where to draw the line.



The RSA and DSA portions are written from number theory and don't use the modules, that was the point. I don't know how to put this in the title without it being edited it out. The RSA and DSA portions are manual implementations of the mathematics. The prime finding algorithms are implementations of two theorems, applied in an order to achieve maximum sieving speed.I did away with my lucas test as doing a large number of Miller Rabin tests produces a probability of 1 of being prime.



I'm using this as an educational tool to force the unwilling learners to kinetically understand public and private key cryptography when passed on a USB etc. in a classroom setting. To see the clicks in peoples eyes when they understand signing or the like, that's why I'm sharing this code. I know there's much better ways to handle the data concatenation, but am happy that I'm processing the data at a binary level.



I love the prime number theorem and so should you.



#!/usr/bin/env python3
import os
import sys
import math
import re
import hashlib
import random
import base64
import string
import getpass
import multiprocessing as mp
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2

#Primality testing, extended greatest common divisor and least common multiple
def isprime(n):
if not n & 1: #check if first bit is 1
return False
for i in (3,5,7,11):
if divmod(n, i)[1] == 0:
return False
#Fermat
if (pow(2, n-1, n)) != 1:
return False
#MilRab, x**2 = 1 mod P - ERH
s = 0
d = n-1
while not d & 1:
d>>=1 #shifts binary rep of number right one place, same as dividing by 2^d
s+=1
assert(2**s * d == n-1) #Process to find s and d
def trial_composite(a):
if pow(a, d, n) == 1:
return False
for i in range(s):
if pow(a, 2**i * d, n) == n-1:
return False
return True
for i in range(100):#Number of Rabin Witness
a = random.randrange(2, n-1)
if trial_composite(a):
return False
return True

def get1prime(keysize):
while True:
p = random.randrange(1<<(keysize), 1<<(keysize+2))
if isprime(p):
return p

def modInverse(a, m) : #Euclid's Extended Algorithm
m0 = m
y = 0
x = 1
while (a > 1) :
q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t
if (x < 0) :
x = x + m0
return x

def lcm(x, y):
lcm = (x*y)//math.gcd(x,y)
return lcm

##AES256CHUNK
def get_private_key(password):
salt = b"We will know, we must know"
kdf = PBKDF2(password, salt, 64, 1000)
key = kdf[:32]
return key

def encryptaes(raw, password):
private_key = password
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))

def decryptaes(enc, password):
private_key = password
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:]))

BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537

def encryptit(e, n, thestring):#for sigining pass d as e
rbinlist = ['{0:08b}'.format(x) for x in thestring]
catstring = ''
catstring += rbinlist[0].lstrip('0')
del rbinlist[0]
for i in rbinlist:
catstring += str(i)
puttynumber = int(catstring,2)
cypherstring = str(pow(puttynumber, e, n))
return cypherstring

def decryptit(d, n, cynum):#for signing pass e as d
decryptmsg = ''
n = int(n)
d = int(d)
puttynum = pow(int(cynum), d, n)
puttynum = '{0:08b}'.format(puttynum)
while True:
if len(puttynum)%8 == 0:
break
puttynum = '0{0}'.format(puttynum)
locs = re.findall('[01]{8}', puttynum)
for x in locs:
letter = chr(int(x,2))
decryptmsg += letter
return decryptmsg

#Begin User Flow
choice = input("""



Welcome to Dan's Cryptography Concept Program.
Generate/Encrypt/Decrypt/Sign
RSA++/DSA++/AES/OTP/Double DH key exch w SHA
Choose:
A: Generate New Public/Private Key Pair
B: Encrypt a File
C: Decrypt a File
=> """)

if choice == 'A' or choice == 'a':
try:
keysize = (int(input("Enter a keysize: "))>>1)
except ValueError as a:
print('Enter a numbernn')
sys.exit()
pubkeyname = input('Input desired public key name: ')
pkey = input('Input desired private key name: ')
pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
print('Generating Keys...')
primes = []
plist = []
for i in range(mp.cpu_count()):
plist.append(keysize)
workpool = mp.Pool(processes=mp.cpu_count())
reslist = workpool.imap_unordered(get1prime, plist)
workpool.close()
for res in reslist:
if res:
primes.append(res)
workpool.terminate()
break
workpool.join()
#
workpool1 = mp.Pool(processes=mp.cpu_count())
reslist = workpool1.imap_unordered(get1prime, plist)
workpool1.close()
for res in reslist:
if res:
primes.append(res)
workpool1.terminate()
break
workpool1.join()
if primes[0] != primes[1]:
p, q = primes[0], primes[1]
else:
print('Supremely Unlucky Try Again')
exit()
n = p*q
cm = lcm(p-1, q-1)
print('Computing Private key ...')
d = modInverse(e, cm)
print('Private Key Size: {} bits'.format(keysize*2))
print('Functional Length of: {}'.format(len(bin((d)))))
keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
with open(pkey, 'w') as f1:
f1.write(str(n)+'n')
f1.write(bytes.decode(keystring))
with open(pubkeyname, 'w') as f2:
f2.write(b64key)
print('Complete - {} and {} generated'.format(pubkeyname,pkey))
print('e exponent: {}'.format(str(e)))
print("""
-----BEGIN PUBLIC KEY-----
{}-----END PUBLIC KEY-----
""".format(b64key))
b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
print("""
-----BEGIN PRIVATE KEY-----
{}-----END PRIVATE KEY-----
""".format(b64privkey))

if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
print('Wrote out to {} '.format(outfile))









share|improve this question









New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$








  • 2




    $begingroup$
    If you have at least one space before the #, the syntax highlighter does not get confused by ' in the comments.
    $endgroup$
    – Graipher
    2 days ago










  • $begingroup$
    To be clear: as this is a teaching aid rather than a practical tool, you're not interested in resistance to information leakage through observation of timing and power consumption, right?
    $endgroup$
    – Toby Speight
    2 days ago










  • $begingroup$
    Well, I'd be interested. The tools is used so students can pass and sign data with public and private keys, just using the program. The internals are my research. I'm extremely curious to know how observing the timing and power could be used to glean meaningful information from either the key generation or encryption.
    $endgroup$
    – dhoyt902
    2 days ago










  • $begingroup$
    Thank you Graipher
    $endgroup$
    – dhoyt902
    2 days ago






  • 1




    $begingroup$
    Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    $endgroup$
    – Mast
    yesterday














8












8








8





$begingroup$


My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk of the data for speed, and encrypts the random key with RSA. Many operations were chosen for speed. This works out of the box on 3.6+ . Windows idle env disallows it from working there, but Linux and mac is ideal. I do call gzip which I know I can replace with a module. I almost want to do my own Huffman coding for it but I don't know where to draw the line.



The RSA and DSA portions are written from number theory and don't use the modules, that was the point. I don't know how to put this in the title without it being edited it out. The RSA and DSA portions are manual implementations of the mathematics. The prime finding algorithms are implementations of two theorems, applied in an order to achieve maximum sieving speed.I did away with my lucas test as doing a large number of Miller Rabin tests produces a probability of 1 of being prime.



I'm using this as an educational tool to force the unwilling learners to kinetically understand public and private key cryptography when passed on a USB etc. in a classroom setting. To see the clicks in peoples eyes when they understand signing or the like, that's why I'm sharing this code. I know there's much better ways to handle the data concatenation, but am happy that I'm processing the data at a binary level.



I love the prime number theorem and so should you.



#!/usr/bin/env python3
import os
import sys
import math
import re
import hashlib
import random
import base64
import string
import getpass
import multiprocessing as mp
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2

#Primality testing, extended greatest common divisor and least common multiple
def isprime(n):
if not n & 1: #check if first bit is 1
return False
for i in (3,5,7,11):
if divmod(n, i)[1] == 0:
return False
#Fermat
if (pow(2, n-1, n)) != 1:
return False
#MilRab, x**2 = 1 mod P - ERH
s = 0
d = n-1
while not d & 1:
d>>=1 #shifts binary rep of number right one place, same as dividing by 2^d
s+=1
assert(2**s * d == n-1) #Process to find s and d
def trial_composite(a):
if pow(a, d, n) == 1:
return False
for i in range(s):
if pow(a, 2**i * d, n) == n-1:
return False
return True
for i in range(100):#Number of Rabin Witness
a = random.randrange(2, n-1)
if trial_composite(a):
return False
return True

def get1prime(keysize):
while True:
p = random.randrange(1<<(keysize), 1<<(keysize+2))
if isprime(p):
return p

def modInverse(a, m) : #Euclid's Extended Algorithm
m0 = m
y = 0
x = 1
while (a > 1) :
q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t
if (x < 0) :
x = x + m0
return x

def lcm(x, y):
lcm = (x*y)//math.gcd(x,y)
return lcm

##AES256CHUNK
def get_private_key(password):
salt = b"We will know, we must know"
kdf = PBKDF2(password, salt, 64, 1000)
key = kdf[:32]
return key

def encryptaes(raw, password):
private_key = password
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))

def decryptaes(enc, password):
private_key = password
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:]))

BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537

def encryptit(e, n, thestring):#for sigining pass d as e
rbinlist = ['{0:08b}'.format(x) for x in thestring]
catstring = ''
catstring += rbinlist[0].lstrip('0')
del rbinlist[0]
for i in rbinlist:
catstring += str(i)
puttynumber = int(catstring,2)
cypherstring = str(pow(puttynumber, e, n))
return cypherstring

def decryptit(d, n, cynum):#for signing pass e as d
decryptmsg = ''
n = int(n)
d = int(d)
puttynum = pow(int(cynum), d, n)
puttynum = '{0:08b}'.format(puttynum)
while True:
if len(puttynum)%8 == 0:
break
puttynum = '0{0}'.format(puttynum)
locs = re.findall('[01]{8}', puttynum)
for x in locs:
letter = chr(int(x,2))
decryptmsg += letter
return decryptmsg

#Begin User Flow
choice = input("""



Welcome to Dan's Cryptography Concept Program.
Generate/Encrypt/Decrypt/Sign
RSA++/DSA++/AES/OTP/Double DH key exch w SHA
Choose:
A: Generate New Public/Private Key Pair
B: Encrypt a File
C: Decrypt a File
=> """)

if choice == 'A' or choice == 'a':
try:
keysize = (int(input("Enter a keysize: "))>>1)
except ValueError as a:
print('Enter a numbernn')
sys.exit()
pubkeyname = input('Input desired public key name: ')
pkey = input('Input desired private key name: ')
pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
print('Generating Keys...')
primes = []
plist = []
for i in range(mp.cpu_count()):
plist.append(keysize)
workpool = mp.Pool(processes=mp.cpu_count())
reslist = workpool.imap_unordered(get1prime, plist)
workpool.close()
for res in reslist:
if res:
primes.append(res)
workpool.terminate()
break
workpool.join()
#
workpool1 = mp.Pool(processes=mp.cpu_count())
reslist = workpool1.imap_unordered(get1prime, plist)
workpool1.close()
for res in reslist:
if res:
primes.append(res)
workpool1.terminate()
break
workpool1.join()
if primes[0] != primes[1]:
p, q = primes[0], primes[1]
else:
print('Supremely Unlucky Try Again')
exit()
n = p*q
cm = lcm(p-1, q-1)
print('Computing Private key ...')
d = modInverse(e, cm)
print('Private Key Size: {} bits'.format(keysize*2))
print('Functional Length of: {}'.format(len(bin((d)))))
keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
with open(pkey, 'w') as f1:
f1.write(str(n)+'n')
f1.write(bytes.decode(keystring))
with open(pubkeyname, 'w') as f2:
f2.write(b64key)
print('Complete - {} and {} generated'.format(pubkeyname,pkey))
print('e exponent: {}'.format(str(e)))
print("""
-----BEGIN PUBLIC KEY-----
{}-----END PUBLIC KEY-----
""".format(b64key))
b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
print("""
-----BEGIN PRIVATE KEY-----
{}-----END PRIVATE KEY-----
""".format(b64privkey))

if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
print('Wrote out to {} '.format(outfile))









share|improve this question









New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$




My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk of the data for speed, and encrypts the random key with RSA. Many operations were chosen for speed. This works out of the box on 3.6+ . Windows idle env disallows it from working there, but Linux and mac is ideal. I do call gzip which I know I can replace with a module. I almost want to do my own Huffman coding for it but I don't know where to draw the line.



The RSA and DSA portions are written from number theory and don't use the modules, that was the point. I don't know how to put this in the title without it being edited it out. The RSA and DSA portions are manual implementations of the mathematics. The prime finding algorithms are implementations of two theorems, applied in an order to achieve maximum sieving speed.I did away with my lucas test as doing a large number of Miller Rabin tests produces a probability of 1 of being prime.



I'm using this as an educational tool to force the unwilling learners to kinetically understand public and private key cryptography when passed on a USB etc. in a classroom setting. To see the clicks in peoples eyes when they understand signing or the like, that's why I'm sharing this code. I know there's much better ways to handle the data concatenation, but am happy that I'm processing the data at a binary level.



I love the prime number theorem and so should you.



#!/usr/bin/env python3
import os
import sys
import math
import re
import hashlib
import random
import base64
import string
import getpass
import multiprocessing as mp
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2

#Primality testing, extended greatest common divisor and least common multiple
def isprime(n):
if not n & 1: #check if first bit is 1
return False
for i in (3,5,7,11):
if divmod(n, i)[1] == 0:
return False
#Fermat
if (pow(2, n-1, n)) != 1:
return False
#MilRab, x**2 = 1 mod P - ERH
s = 0
d = n-1
while not d & 1:
d>>=1 #shifts binary rep of number right one place, same as dividing by 2^d
s+=1
assert(2**s * d == n-1) #Process to find s and d
def trial_composite(a):
if pow(a, d, n) == 1:
return False
for i in range(s):
if pow(a, 2**i * d, n) == n-1:
return False
return True
for i in range(100):#Number of Rabin Witness
a = random.randrange(2, n-1)
if trial_composite(a):
return False
return True

def get1prime(keysize):
while True:
p = random.randrange(1<<(keysize), 1<<(keysize+2))
if isprime(p):
return p

def modInverse(a, m) : #Euclid's Extended Algorithm
m0 = m
y = 0
x = 1
while (a > 1) :
q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t
if (x < 0) :
x = x + m0
return x

def lcm(x, y):
lcm = (x*y)//math.gcd(x,y)
return lcm

##AES256CHUNK
def get_private_key(password):
salt = b"We will know, we must know"
kdf = PBKDF2(password, salt, 64, 1000)
key = kdf[:32]
return key

def encryptaes(raw, password):
private_key = password
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))

def decryptaes(enc, password):
private_key = password
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:]))

BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537

def encryptit(e, n, thestring):#for sigining pass d as e
rbinlist = ['{0:08b}'.format(x) for x in thestring]
catstring = ''
catstring += rbinlist[0].lstrip('0')
del rbinlist[0]
for i in rbinlist:
catstring += str(i)
puttynumber = int(catstring,2)
cypherstring = str(pow(puttynumber, e, n))
return cypherstring

def decryptit(d, n, cynum):#for signing pass e as d
decryptmsg = ''
n = int(n)
d = int(d)
puttynum = pow(int(cynum), d, n)
puttynum = '{0:08b}'.format(puttynum)
while True:
if len(puttynum)%8 == 0:
break
puttynum = '0{0}'.format(puttynum)
locs = re.findall('[01]{8}', puttynum)
for x in locs:
letter = chr(int(x,2))
decryptmsg += letter
return decryptmsg

#Begin User Flow
choice = input("""



Welcome to Dan's Cryptography Concept Program.
Generate/Encrypt/Decrypt/Sign
RSA++/DSA++/AES/OTP/Double DH key exch w SHA
Choose:
A: Generate New Public/Private Key Pair
B: Encrypt a File
C: Decrypt a File
=> """)

if choice == 'A' or choice == 'a':
try:
keysize = (int(input("Enter a keysize: "))>>1)
except ValueError as a:
print('Enter a numbernn')
sys.exit()
pubkeyname = input('Input desired public key name: ')
pkey = input('Input desired private key name: ')
pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
print('Generating Keys...')
primes = []
plist = []
for i in range(mp.cpu_count()):
plist.append(keysize)
workpool = mp.Pool(processes=mp.cpu_count())
reslist = workpool.imap_unordered(get1prime, plist)
workpool.close()
for res in reslist:
if res:
primes.append(res)
workpool.terminate()
break
workpool.join()
#
workpool1 = mp.Pool(processes=mp.cpu_count())
reslist = workpool1.imap_unordered(get1prime, plist)
workpool1.close()
for res in reslist:
if res:
primes.append(res)
workpool1.terminate()
break
workpool1.join()
if primes[0] != primes[1]:
p, q = primes[0], primes[1]
else:
print('Supremely Unlucky Try Again')
exit()
n = p*q
cm = lcm(p-1, q-1)
print('Computing Private key ...')
d = modInverse(e, cm)
print('Private Key Size: {} bits'.format(keysize*2))
print('Functional Length of: {}'.format(len(bin((d)))))
keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
with open(pkey, 'w') as f1:
f1.write(str(n)+'n')
f1.write(bytes.decode(keystring))
with open(pubkeyname, 'w') as f2:
f2.write(b64key)
print('Complete - {} and {} generated'.format(pubkeyname,pkey))
print('e exponent: {}'.format(str(e)))
print("""
-----BEGIN PUBLIC KEY-----
{}-----END PUBLIC KEY-----
""".format(b64key))
b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
print("""
-----BEGIN PRIVATE KEY-----
{}-----END PRIVATE KEY-----
""".format(b64privkey))

if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
print('Wrote out to {} '.format(outfile))






python python-3.x cryptography






share|improve this question









New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited yesterday









Mast

7,54163788




7,54163788






New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 2 days ago









dhoyt902dhoyt902

444




444




New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 2




    $begingroup$
    If you have at least one space before the #, the syntax highlighter does not get confused by ' in the comments.
    $endgroup$
    – Graipher
    2 days ago










  • $begingroup$
    To be clear: as this is a teaching aid rather than a practical tool, you're not interested in resistance to information leakage through observation of timing and power consumption, right?
    $endgroup$
    – Toby Speight
    2 days ago










  • $begingroup$
    Well, I'd be interested. The tools is used so students can pass and sign data with public and private keys, just using the program. The internals are my research. I'm extremely curious to know how observing the timing and power could be used to glean meaningful information from either the key generation or encryption.
    $endgroup$
    – dhoyt902
    2 days ago










  • $begingroup$
    Thank you Graipher
    $endgroup$
    – dhoyt902
    2 days ago






  • 1




    $begingroup$
    Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    $endgroup$
    – Mast
    yesterday














  • 2




    $begingroup$
    If you have at least one space before the #, the syntax highlighter does not get confused by ' in the comments.
    $endgroup$
    – Graipher
    2 days ago










  • $begingroup$
    To be clear: as this is a teaching aid rather than a practical tool, you're not interested in resistance to information leakage through observation of timing and power consumption, right?
    $endgroup$
    – Toby Speight
    2 days ago










  • $begingroup$
    Well, I'd be interested. The tools is used so students can pass and sign data with public and private keys, just using the program. The internals are my research. I'm extremely curious to know how observing the timing and power could be used to glean meaningful information from either the key generation or encryption.
    $endgroup$
    – dhoyt902
    2 days ago










  • $begingroup$
    Thank you Graipher
    $endgroup$
    – dhoyt902
    2 days ago






  • 1




    $begingroup$
    Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    $endgroup$
    – Mast
    yesterday








2




2




$begingroup$
If you have at least one space before the #, the syntax highlighter does not get confused by ' in the comments.
$endgroup$
– Graipher
2 days ago




$begingroup$
If you have at least one space before the #, the syntax highlighter does not get confused by ' in the comments.
$endgroup$
– Graipher
2 days ago












$begingroup$
To be clear: as this is a teaching aid rather than a practical tool, you're not interested in resistance to information leakage through observation of timing and power consumption, right?
$endgroup$
– Toby Speight
2 days ago




$begingroup$
To be clear: as this is a teaching aid rather than a practical tool, you're not interested in resistance to information leakage through observation of timing and power consumption, right?
$endgroup$
– Toby Speight
2 days ago












$begingroup$
Well, I'd be interested. The tools is used so students can pass and sign data with public and private keys, just using the program. The internals are my research. I'm extremely curious to know how observing the timing and power could be used to glean meaningful information from either the key generation or encryption.
$endgroup$
– dhoyt902
2 days ago




$begingroup$
Well, I'd be interested. The tools is used so students can pass and sign data with public and private keys, just using the program. The internals are my research. I'm extremely curious to know how observing the timing and power could be used to glean meaningful information from either the key generation or encryption.
$endgroup$
– dhoyt902
2 days ago












$begingroup$
Thank you Graipher
$endgroup$
– dhoyt902
2 days ago




$begingroup$
Thank you Graipher
$endgroup$
– dhoyt902
2 days ago




1




1




$begingroup$
Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
$endgroup$
– Mast
yesterday




$begingroup$
Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
$endgroup$
– Mast
yesterday










3 Answers
3






active

oldest

votes


















2












$begingroup$

Here's a couple small points that aren't a full review, but might be helpful.



% exists instead of divmod for when you only care about the modulo.



In modInverse



   q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t


could be written more clearly as



   q = a // m
t = m
a, m = m, a%m
x, y = y, x - q*y


For LCM computation, you should probably rewrite it as return x//math.gcd(x,y) * y as that will keep your numbers smaller, which is always nice (especially when x and y might both be big).



Also, you're RSA implementation isn't secure for details of why see textbook rsa flaws. If you care, the solution is to use something like PKCS which is a padding scheme to provide semantic security, and to fix some other problems.






share|improve this answer









$endgroup$













  • $begingroup$
    Thank you Oscar! I chose the divmod for performance. Unfortunately despite the ugliness it runs faster on my machine for a 100k runs etc. Thank you for the return pointer, I shall do that. Also, I shall add a padding to the RSA, that should be straight forward.
    $endgroup$
    – dhoyt902
    yesterday












  • $begingroup$
    If you actually care about max performance, you should be using gmpy. For big numbers, it will make everything faster.
    $endgroup$
    – Oscar Smith
    yesterday










  • $begingroup$
    Though stepping away from the builtins, at this point that'd be nice. Do you mean use gmpy's mpz() type for the numbers? (bc also gmpy can just detect primes with every major test)
    $endgroup$
    – dhoyt902
    yesterday












  • $begingroup$
    yes they have a mutable type, but it's really hard to use rigth
    $endgroup$
    – Oscar Smith
    yesterday



















0












$begingroup$

Here is the padded improved code from the suggestions here:



#!/usr/bin/env python3
import os
import sys
import math
import re
import hashlib
import random
import base64
import string
import getpass
import multiprocessing as mp
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2
#Non builtins
from gmpy2 import is_prime as isprime
from gmpy2 import is_strong_bpsw_prp as ispprime
#Primality testing, extended greatest common divisor and least common multiple

def get1prime(keysize):
while True:
p = random.randrange(1<<(keysize), 1<<(keysize+2))
if isprime(p):
if ispprime(p):
return p

def modInverse(a, m) : #Euclid's Extended Algorithm
m0 = m
y = 0
x = 1
while (a > 1) :
q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t
if (x < 0) :
x = x + m0
return x

def lcm(x, y):
return (x*y)//math.gcd(x,y)

##AES256CHUNK
def get_private_key(password):
salt = b"We will know, we must know"
kdf = PBKDF2(password, salt, 64, 1000)
key = kdf[:32]
return key

def encryptaes(raw, password):
private_key = password
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))

def decryptaes(enc, password):
private_key = password
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:]))

BLOCK_SIZE = 64 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537

def encryptit(e, n, thestring):#for sigining pass d as e
thestring = pad(str(thestring)).encode()
rbinlist = ['{0:08b}'.format(x) for x in thestring]
catstring = ''
catstring += rbinlist[0].lstrip('0')
del rbinlist[0]
for i in rbinlist:
catstring += str(i)
puttynumber = int(catstring,2)
cypherstring = str(pow(puttynumber, e, n))
return cypherstring

def decryptit(d, n, cynum):#for signing pass e as d
decryptmsg = ''
n = int(n)
d = int(d)
puttynum = pow(int(cynum), d, n)
puttynum = '{0:08b}'.format(puttynum)
while True:
if len(puttynum)%8 == 0:
break
puttynum = '0{0}'.format(puttynum)
locs = re.findall('[01]{8}', puttynum)
for x in locs:
letter = chr(int(x,2))
decryptmsg += letter
return unpad(decryptmsg)[2:-1]

#Begin User Flow
choice = input("""
██████╗ ██████╗ ██╗ ██╗██████╗ ████████╗
██╔════╝ ██╔══██╗╚██╗ ██╔╝██╔══██╗╚══██╔══╝
██║ ███╗██████╔╝ ╚████╔╝ ██████╔╝ ██║
██║ ██║██╔══██╗ ╚██╔╝ ██╔═══╝ ██║
╚██████╔╝██║ ██║ ██║ ██║ ██║
╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═
Welcome to Dan's Cryptography Concept Program.
Generate/Encrypt/Decrypt/Sign
RSA++/DSA++/AES/OTP/Double DH key exch w SHA
Choose:
A: Generate New Public/Private Key Pair
B: Encrypt a File
C: Decrypt a File
=> """)

if choice == 'A' or choice == 'a':
try:
keysize = (int(input("Enter a keysize: "))>>1)
except ValueError as a:
print('Enter a numbernn')
sys.exit()
pubkeyname = input('Input desired public key name: ')
pkey = input('Input desired private key name: ')
pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
print('Generating Keys...')
primes = []
plist = []
for i in range(mp.cpu_count()):
plist.append(keysize)
workpool = mp.Pool(processes=mp.cpu_count())
reslist = workpool.imap_unordered(get1prime, plist)
workpool.close()
for res in reslist:
if res:
primes.append(res)
workpool.terminate()
break
workpool.join()
#
workpool1 = mp.Pool(processes=mp.cpu_count())
reslist = workpool1.imap_unordered(get1prime, plist)
workpool1.close()
for res in reslist:
if res:
primes.append(res)
workpool1.terminate()
break
workpool1.join()
if primes[0] != primes[1]:
p, q = primes[0], primes[1]
else:
print('Supremely Unlucky Try Again')
exit()
n = p*q
cm = lcm(p-1, q-1)
print('Computing Private key ...')
d = modInverse(e, cm)
print('Private Key Size: {} bits'.format(keysize*2))
print('Functional Length of: {}'.format(len(bin((d)))))
keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
with open(pkey, 'w') as f1:
f1.write(str(n)+'n')
f1.write(bytes.decode(keystring))
with open(pubkeyname, 'w') as f2:
f2.write(b64key)
print('Complete - {} and {} generated'.format(pubkeyname,pkey))
print('e exponent: {}'.format(str(e)))
print("""
-----BEGIN PUBLIC KEY-----
{}-----END PUBLIC KEY-----
""".format(b64key))
b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
print("""
-----BEGIN PRIVATE KEY-----
{}-----END PRIVATE KEY-----
""".format(b64privkey))

if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
os.system('gzip -9 {0};mv {0}.gz {0}'.format(workfile))
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0};mv {1} {1}.gz;gzip -d {1}'.format(outfile, workfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
os.system('mv {0} {0}.gz;gzip -d {0}.gz;rm {1}'.format(outfile, workfile))
print('Wrote out to {} '.format(outfile))





share|improve this answer










New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$













  • $begingroup$
    This is a very good question and a nice tool. I suggest that you also try my suggestions as well. Your code is still hard to read. Lot more will benefit that way. :) You can also post this code or further edited code as another question so people will also review it.
    $endgroup$
    – 422_unprocessable_entity
    yesterday



















0












$begingroup$

This is nice work. Very useful educational tool. Keep up the good work.



Now for some nitpicking:




def isprime(n):




  • This function has too much things going on in it. Can you break it to smaller functions by refactor extract function?



def isprime(n):
if not n & 1: #check if first bit is 1

#Fermat

#MilRab, x**2 = 1 mod P - ERH

def trial_composite(a):

for i in range(100): #Number of Rabin Witness




  • Every-time you have the urge to add comments like this it means there is something wrong. Extract functions.

  • Also if possible trial_composite should also go outside. But I can see this might not be possible.



def modInverse(a, m):
m0 = m




  • This function is really hard to understand. Please avoid using single letter variables. Rename them to something meaningful.

  • You are using a all over the place. I have no idea what it even means. Try to have meaningful parameters and variables.

  • Please add spaces before and after # comments.



BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537




  • Please define constants at the top so it's easier to read.

  • Why are you naming the lambda functions? Use a def if you want a name.

  • What is e here? name it properly so you don't need to comment.



modInverse




  • Please use snake_case to name functions. Why: Industry standard. PEP-8. You can use autopep8 or black to format your code.



if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
print('Wrote out to {} '.format(outfile))




  • Please don't jam your code together. You are not writing code in an A4 sheet.

  • Please add meaningful and logical separation.

  • This could also use some extract function refactoring.



os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))




  • Python already have shutil and gzip modules. They can move, copy files, folders and gzip stuff for you. It would be little more code, but your code can be easily made cross platform this way.






share|improve this answer











$endgroup$













  • $begingroup$
    Thank you 422!! This is great! I shall try to implement your suggestions - though the modular inverse will be hard to make clearer, its easier done on paper. I'll likely need to think for a bit on how to refactor certain bits, put I shall post the updated code either here or a new question.
    $endgroup$
    – dhoyt902
    yesterday










  • $begingroup$
    @dhoyt902 Create a new question titled Generate public/private keys, encrypt, decrypt, sign, verify v2.0 (You may also change v2.0 to something else you wish like for example follow-up). Plus asking a new question will give you more upvotes :)
    $endgroup$
    – 422_unprocessable_entity
    yesterday












  • $begingroup$
    @dhoyt902 Also added more info on how you can format code.
    $endgroup$
    – 422_unprocessable_entity
    yesterday











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






dhoyt902 is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214375%2fgenerate-public-private-keys-encrypt-decrypt-sign-verify%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









2












$begingroup$

Here's a couple small points that aren't a full review, but might be helpful.



% exists instead of divmod for when you only care about the modulo.



In modInverse



   q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t


could be written more clearly as



   q = a // m
t = m
a, m = m, a%m
x, y = y, x - q*y


For LCM computation, you should probably rewrite it as return x//math.gcd(x,y) * y as that will keep your numbers smaller, which is always nice (especially when x and y might both be big).



Also, you're RSA implementation isn't secure for details of why see textbook rsa flaws. If you care, the solution is to use something like PKCS which is a padding scheme to provide semantic security, and to fix some other problems.






share|improve this answer









$endgroup$













  • $begingroup$
    Thank you Oscar! I chose the divmod for performance. Unfortunately despite the ugliness it runs faster on my machine for a 100k runs etc. Thank you for the return pointer, I shall do that. Also, I shall add a padding to the RSA, that should be straight forward.
    $endgroup$
    – dhoyt902
    yesterday












  • $begingroup$
    If you actually care about max performance, you should be using gmpy. For big numbers, it will make everything faster.
    $endgroup$
    – Oscar Smith
    yesterday










  • $begingroup$
    Though stepping away from the builtins, at this point that'd be nice. Do you mean use gmpy's mpz() type for the numbers? (bc also gmpy can just detect primes with every major test)
    $endgroup$
    – dhoyt902
    yesterday












  • $begingroup$
    yes they have a mutable type, but it's really hard to use rigth
    $endgroup$
    – Oscar Smith
    yesterday
















2












$begingroup$

Here's a couple small points that aren't a full review, but might be helpful.



% exists instead of divmod for when you only care about the modulo.



In modInverse



   q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t


could be written more clearly as



   q = a // m
t = m
a, m = m, a%m
x, y = y, x - q*y


For LCM computation, you should probably rewrite it as return x//math.gcd(x,y) * y as that will keep your numbers smaller, which is always nice (especially when x and y might both be big).



Also, you're RSA implementation isn't secure for details of why see textbook rsa flaws. If you care, the solution is to use something like PKCS which is a padding scheme to provide semantic security, and to fix some other problems.






share|improve this answer









$endgroup$













  • $begingroup$
    Thank you Oscar! I chose the divmod for performance. Unfortunately despite the ugliness it runs faster on my machine for a 100k runs etc. Thank you for the return pointer, I shall do that. Also, I shall add a padding to the RSA, that should be straight forward.
    $endgroup$
    – dhoyt902
    yesterday












  • $begingroup$
    If you actually care about max performance, you should be using gmpy. For big numbers, it will make everything faster.
    $endgroup$
    – Oscar Smith
    yesterday










  • $begingroup$
    Though stepping away from the builtins, at this point that'd be nice. Do you mean use gmpy's mpz() type for the numbers? (bc also gmpy can just detect primes with every major test)
    $endgroup$
    – dhoyt902
    yesterday












  • $begingroup$
    yes they have a mutable type, but it's really hard to use rigth
    $endgroup$
    – Oscar Smith
    yesterday














2












2








2





$begingroup$

Here's a couple small points that aren't a full review, but might be helpful.



% exists instead of divmod for when you only care about the modulo.



In modInverse



   q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t


could be written more clearly as



   q = a // m
t = m
a, m = m, a%m
x, y = y, x - q*y


For LCM computation, you should probably rewrite it as return x//math.gcd(x,y) * y as that will keep your numbers smaller, which is always nice (especially when x and y might both be big).



Also, you're RSA implementation isn't secure for details of why see textbook rsa flaws. If you care, the solution is to use something like PKCS which is a padding scheme to provide semantic security, and to fix some other problems.






share|improve this answer









$endgroup$



Here's a couple small points that aren't a full review, but might be helpful.



% exists instead of divmod for when you only care about the modulo.



In modInverse



   q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t


could be written more clearly as



   q = a // m
t = m
a, m = m, a%m
x, y = y, x - q*y


For LCM computation, you should probably rewrite it as return x//math.gcd(x,y) * y as that will keep your numbers smaller, which is always nice (especially when x and y might both be big).



Also, you're RSA implementation isn't secure for details of why see textbook rsa flaws. If you care, the solution is to use something like PKCS which is a padding scheme to provide semantic security, and to fix some other problems.







share|improve this answer












share|improve this answer



share|improve this answer










answered yesterday









Oscar SmithOscar Smith

2,7731022




2,7731022












  • $begingroup$
    Thank you Oscar! I chose the divmod for performance. Unfortunately despite the ugliness it runs faster on my machine for a 100k runs etc. Thank you for the return pointer, I shall do that. Also, I shall add a padding to the RSA, that should be straight forward.
    $endgroup$
    – dhoyt902
    yesterday












  • $begingroup$
    If you actually care about max performance, you should be using gmpy. For big numbers, it will make everything faster.
    $endgroup$
    – Oscar Smith
    yesterday










  • $begingroup$
    Though stepping away from the builtins, at this point that'd be nice. Do you mean use gmpy's mpz() type for the numbers? (bc also gmpy can just detect primes with every major test)
    $endgroup$
    – dhoyt902
    yesterday












  • $begingroup$
    yes they have a mutable type, but it's really hard to use rigth
    $endgroup$
    – Oscar Smith
    yesterday


















  • $begingroup$
    Thank you Oscar! I chose the divmod for performance. Unfortunately despite the ugliness it runs faster on my machine for a 100k runs etc. Thank you for the return pointer, I shall do that. Also, I shall add a padding to the RSA, that should be straight forward.
    $endgroup$
    – dhoyt902
    yesterday












  • $begingroup$
    If you actually care about max performance, you should be using gmpy. For big numbers, it will make everything faster.
    $endgroup$
    – Oscar Smith
    yesterday










  • $begingroup$
    Though stepping away from the builtins, at this point that'd be nice. Do you mean use gmpy's mpz() type for the numbers? (bc also gmpy can just detect primes with every major test)
    $endgroup$
    – dhoyt902
    yesterday












  • $begingroup$
    yes they have a mutable type, but it's really hard to use rigth
    $endgroup$
    – Oscar Smith
    yesterday
















$begingroup$
Thank you Oscar! I chose the divmod for performance. Unfortunately despite the ugliness it runs faster on my machine for a 100k runs etc. Thank you for the return pointer, I shall do that. Also, I shall add a padding to the RSA, that should be straight forward.
$endgroup$
– dhoyt902
yesterday






$begingroup$
Thank you Oscar! I chose the divmod for performance. Unfortunately despite the ugliness it runs faster on my machine for a 100k runs etc. Thank you for the return pointer, I shall do that. Also, I shall add a padding to the RSA, that should be straight forward.
$endgroup$
– dhoyt902
yesterday














$begingroup$
If you actually care about max performance, you should be using gmpy. For big numbers, it will make everything faster.
$endgroup$
– Oscar Smith
yesterday




$begingroup$
If you actually care about max performance, you should be using gmpy. For big numbers, it will make everything faster.
$endgroup$
– Oscar Smith
yesterday












$begingroup$
Though stepping away from the builtins, at this point that'd be nice. Do you mean use gmpy's mpz() type for the numbers? (bc also gmpy can just detect primes with every major test)
$endgroup$
– dhoyt902
yesterday






$begingroup$
Though stepping away from the builtins, at this point that'd be nice. Do you mean use gmpy's mpz() type for the numbers? (bc also gmpy can just detect primes with every major test)
$endgroup$
– dhoyt902
yesterday














$begingroup$
yes they have a mutable type, but it's really hard to use rigth
$endgroup$
– Oscar Smith
yesterday




$begingroup$
yes they have a mutable type, but it's really hard to use rigth
$endgroup$
– Oscar Smith
yesterday













0












$begingroup$

Here is the padded improved code from the suggestions here:



#!/usr/bin/env python3
import os
import sys
import math
import re
import hashlib
import random
import base64
import string
import getpass
import multiprocessing as mp
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2
#Non builtins
from gmpy2 import is_prime as isprime
from gmpy2 import is_strong_bpsw_prp as ispprime
#Primality testing, extended greatest common divisor and least common multiple

def get1prime(keysize):
while True:
p = random.randrange(1<<(keysize), 1<<(keysize+2))
if isprime(p):
if ispprime(p):
return p

def modInverse(a, m) : #Euclid's Extended Algorithm
m0 = m
y = 0
x = 1
while (a > 1) :
q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t
if (x < 0) :
x = x + m0
return x

def lcm(x, y):
return (x*y)//math.gcd(x,y)

##AES256CHUNK
def get_private_key(password):
salt = b"We will know, we must know"
kdf = PBKDF2(password, salt, 64, 1000)
key = kdf[:32]
return key

def encryptaes(raw, password):
private_key = password
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))

def decryptaes(enc, password):
private_key = password
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:]))

BLOCK_SIZE = 64 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537

def encryptit(e, n, thestring):#for sigining pass d as e
thestring = pad(str(thestring)).encode()
rbinlist = ['{0:08b}'.format(x) for x in thestring]
catstring = ''
catstring += rbinlist[0].lstrip('0')
del rbinlist[0]
for i in rbinlist:
catstring += str(i)
puttynumber = int(catstring,2)
cypherstring = str(pow(puttynumber, e, n))
return cypherstring

def decryptit(d, n, cynum):#for signing pass e as d
decryptmsg = ''
n = int(n)
d = int(d)
puttynum = pow(int(cynum), d, n)
puttynum = '{0:08b}'.format(puttynum)
while True:
if len(puttynum)%8 == 0:
break
puttynum = '0{0}'.format(puttynum)
locs = re.findall('[01]{8}', puttynum)
for x in locs:
letter = chr(int(x,2))
decryptmsg += letter
return unpad(decryptmsg)[2:-1]

#Begin User Flow
choice = input("""
██████╗ ██████╗ ██╗ ██╗██████╗ ████████╗
██╔════╝ ██╔══██╗╚██╗ ██╔╝██╔══██╗╚══██╔══╝
██║ ███╗██████╔╝ ╚████╔╝ ██████╔╝ ██║
██║ ██║██╔══██╗ ╚██╔╝ ██╔═══╝ ██║
╚██████╔╝██║ ██║ ██║ ██║ ██║
╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═
Welcome to Dan's Cryptography Concept Program.
Generate/Encrypt/Decrypt/Sign
RSA++/DSA++/AES/OTP/Double DH key exch w SHA
Choose:
A: Generate New Public/Private Key Pair
B: Encrypt a File
C: Decrypt a File
=> """)

if choice == 'A' or choice == 'a':
try:
keysize = (int(input("Enter a keysize: "))>>1)
except ValueError as a:
print('Enter a numbernn')
sys.exit()
pubkeyname = input('Input desired public key name: ')
pkey = input('Input desired private key name: ')
pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
print('Generating Keys...')
primes = []
plist = []
for i in range(mp.cpu_count()):
plist.append(keysize)
workpool = mp.Pool(processes=mp.cpu_count())
reslist = workpool.imap_unordered(get1prime, plist)
workpool.close()
for res in reslist:
if res:
primes.append(res)
workpool.terminate()
break
workpool.join()
#
workpool1 = mp.Pool(processes=mp.cpu_count())
reslist = workpool1.imap_unordered(get1prime, plist)
workpool1.close()
for res in reslist:
if res:
primes.append(res)
workpool1.terminate()
break
workpool1.join()
if primes[0] != primes[1]:
p, q = primes[0], primes[1]
else:
print('Supremely Unlucky Try Again')
exit()
n = p*q
cm = lcm(p-1, q-1)
print('Computing Private key ...')
d = modInverse(e, cm)
print('Private Key Size: {} bits'.format(keysize*2))
print('Functional Length of: {}'.format(len(bin((d)))))
keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
with open(pkey, 'w') as f1:
f1.write(str(n)+'n')
f1.write(bytes.decode(keystring))
with open(pubkeyname, 'w') as f2:
f2.write(b64key)
print('Complete - {} and {} generated'.format(pubkeyname,pkey))
print('e exponent: {}'.format(str(e)))
print("""
-----BEGIN PUBLIC KEY-----
{}-----END PUBLIC KEY-----
""".format(b64key))
b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
print("""
-----BEGIN PRIVATE KEY-----
{}-----END PRIVATE KEY-----
""".format(b64privkey))

if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
os.system('gzip -9 {0};mv {0}.gz {0}'.format(workfile))
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0};mv {1} {1}.gz;gzip -d {1}'.format(outfile, workfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
os.system('mv {0} {0}.gz;gzip -d {0}.gz;rm {1}'.format(outfile, workfile))
print('Wrote out to {} '.format(outfile))





share|improve this answer










New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$













  • $begingroup$
    This is a very good question and a nice tool. I suggest that you also try my suggestions as well. Your code is still hard to read. Lot more will benefit that way. :) You can also post this code or further edited code as another question so people will also review it.
    $endgroup$
    – 422_unprocessable_entity
    yesterday
















0












$begingroup$

Here is the padded improved code from the suggestions here:



#!/usr/bin/env python3
import os
import sys
import math
import re
import hashlib
import random
import base64
import string
import getpass
import multiprocessing as mp
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2
#Non builtins
from gmpy2 import is_prime as isprime
from gmpy2 import is_strong_bpsw_prp as ispprime
#Primality testing, extended greatest common divisor and least common multiple

def get1prime(keysize):
while True:
p = random.randrange(1<<(keysize), 1<<(keysize+2))
if isprime(p):
if ispprime(p):
return p

def modInverse(a, m) : #Euclid's Extended Algorithm
m0 = m
y = 0
x = 1
while (a > 1) :
q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t
if (x < 0) :
x = x + m0
return x

def lcm(x, y):
return (x*y)//math.gcd(x,y)

##AES256CHUNK
def get_private_key(password):
salt = b"We will know, we must know"
kdf = PBKDF2(password, salt, 64, 1000)
key = kdf[:32]
return key

def encryptaes(raw, password):
private_key = password
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))

def decryptaes(enc, password):
private_key = password
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:]))

BLOCK_SIZE = 64 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537

def encryptit(e, n, thestring):#for sigining pass d as e
thestring = pad(str(thestring)).encode()
rbinlist = ['{0:08b}'.format(x) for x in thestring]
catstring = ''
catstring += rbinlist[0].lstrip('0')
del rbinlist[0]
for i in rbinlist:
catstring += str(i)
puttynumber = int(catstring,2)
cypherstring = str(pow(puttynumber, e, n))
return cypherstring

def decryptit(d, n, cynum):#for signing pass e as d
decryptmsg = ''
n = int(n)
d = int(d)
puttynum = pow(int(cynum), d, n)
puttynum = '{0:08b}'.format(puttynum)
while True:
if len(puttynum)%8 == 0:
break
puttynum = '0{0}'.format(puttynum)
locs = re.findall('[01]{8}', puttynum)
for x in locs:
letter = chr(int(x,2))
decryptmsg += letter
return unpad(decryptmsg)[2:-1]

#Begin User Flow
choice = input("""
██████╗ ██████╗ ██╗ ██╗██████╗ ████████╗
██╔════╝ ██╔══██╗╚██╗ ██╔╝██╔══██╗╚══██╔══╝
██║ ███╗██████╔╝ ╚████╔╝ ██████╔╝ ██║
██║ ██║██╔══██╗ ╚██╔╝ ██╔═══╝ ██║
╚██████╔╝██║ ██║ ██║ ██║ ██║
╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═
Welcome to Dan's Cryptography Concept Program.
Generate/Encrypt/Decrypt/Sign
RSA++/DSA++/AES/OTP/Double DH key exch w SHA
Choose:
A: Generate New Public/Private Key Pair
B: Encrypt a File
C: Decrypt a File
=> """)

if choice == 'A' or choice == 'a':
try:
keysize = (int(input("Enter a keysize: "))>>1)
except ValueError as a:
print('Enter a numbernn')
sys.exit()
pubkeyname = input('Input desired public key name: ')
pkey = input('Input desired private key name: ')
pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
print('Generating Keys...')
primes = []
plist = []
for i in range(mp.cpu_count()):
plist.append(keysize)
workpool = mp.Pool(processes=mp.cpu_count())
reslist = workpool.imap_unordered(get1prime, plist)
workpool.close()
for res in reslist:
if res:
primes.append(res)
workpool.terminate()
break
workpool.join()
#
workpool1 = mp.Pool(processes=mp.cpu_count())
reslist = workpool1.imap_unordered(get1prime, plist)
workpool1.close()
for res in reslist:
if res:
primes.append(res)
workpool1.terminate()
break
workpool1.join()
if primes[0] != primes[1]:
p, q = primes[0], primes[1]
else:
print('Supremely Unlucky Try Again')
exit()
n = p*q
cm = lcm(p-1, q-1)
print('Computing Private key ...')
d = modInverse(e, cm)
print('Private Key Size: {} bits'.format(keysize*2))
print('Functional Length of: {}'.format(len(bin((d)))))
keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
with open(pkey, 'w') as f1:
f1.write(str(n)+'n')
f1.write(bytes.decode(keystring))
with open(pubkeyname, 'w') as f2:
f2.write(b64key)
print('Complete - {} and {} generated'.format(pubkeyname,pkey))
print('e exponent: {}'.format(str(e)))
print("""
-----BEGIN PUBLIC KEY-----
{}-----END PUBLIC KEY-----
""".format(b64key))
b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
print("""
-----BEGIN PRIVATE KEY-----
{}-----END PRIVATE KEY-----
""".format(b64privkey))

if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
os.system('gzip -9 {0};mv {0}.gz {0}'.format(workfile))
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0};mv {1} {1}.gz;gzip -d {1}'.format(outfile, workfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
os.system('mv {0} {0}.gz;gzip -d {0}.gz;rm {1}'.format(outfile, workfile))
print('Wrote out to {} '.format(outfile))





share|improve this answer










New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$













  • $begingroup$
    This is a very good question and a nice tool. I suggest that you also try my suggestions as well. Your code is still hard to read. Lot more will benefit that way. :) You can also post this code or further edited code as another question so people will also review it.
    $endgroup$
    – 422_unprocessable_entity
    yesterday














0












0








0





$begingroup$

Here is the padded improved code from the suggestions here:



#!/usr/bin/env python3
import os
import sys
import math
import re
import hashlib
import random
import base64
import string
import getpass
import multiprocessing as mp
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2
#Non builtins
from gmpy2 import is_prime as isprime
from gmpy2 import is_strong_bpsw_prp as ispprime
#Primality testing, extended greatest common divisor and least common multiple

def get1prime(keysize):
while True:
p = random.randrange(1<<(keysize), 1<<(keysize+2))
if isprime(p):
if ispprime(p):
return p

def modInverse(a, m) : #Euclid's Extended Algorithm
m0 = m
y = 0
x = 1
while (a > 1) :
q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t
if (x < 0) :
x = x + m0
return x

def lcm(x, y):
return (x*y)//math.gcd(x,y)

##AES256CHUNK
def get_private_key(password):
salt = b"We will know, we must know"
kdf = PBKDF2(password, salt, 64, 1000)
key = kdf[:32]
return key

def encryptaes(raw, password):
private_key = password
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))

def decryptaes(enc, password):
private_key = password
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:]))

BLOCK_SIZE = 64 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537

def encryptit(e, n, thestring):#for sigining pass d as e
thestring = pad(str(thestring)).encode()
rbinlist = ['{0:08b}'.format(x) for x in thestring]
catstring = ''
catstring += rbinlist[0].lstrip('0')
del rbinlist[0]
for i in rbinlist:
catstring += str(i)
puttynumber = int(catstring,2)
cypherstring = str(pow(puttynumber, e, n))
return cypherstring

def decryptit(d, n, cynum):#for signing pass e as d
decryptmsg = ''
n = int(n)
d = int(d)
puttynum = pow(int(cynum), d, n)
puttynum = '{0:08b}'.format(puttynum)
while True:
if len(puttynum)%8 == 0:
break
puttynum = '0{0}'.format(puttynum)
locs = re.findall('[01]{8}', puttynum)
for x in locs:
letter = chr(int(x,2))
decryptmsg += letter
return unpad(decryptmsg)[2:-1]

#Begin User Flow
choice = input("""
██████╗ ██████╗ ██╗ ██╗██████╗ ████████╗
██╔════╝ ██╔══██╗╚██╗ ██╔╝██╔══██╗╚══██╔══╝
██║ ███╗██████╔╝ ╚████╔╝ ██████╔╝ ██║
██║ ██║██╔══██╗ ╚██╔╝ ██╔═══╝ ██║
╚██████╔╝██║ ██║ ██║ ██║ ██║
╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═
Welcome to Dan's Cryptography Concept Program.
Generate/Encrypt/Decrypt/Sign
RSA++/DSA++/AES/OTP/Double DH key exch w SHA
Choose:
A: Generate New Public/Private Key Pair
B: Encrypt a File
C: Decrypt a File
=> """)

if choice == 'A' or choice == 'a':
try:
keysize = (int(input("Enter a keysize: "))>>1)
except ValueError as a:
print('Enter a numbernn')
sys.exit()
pubkeyname = input('Input desired public key name: ')
pkey = input('Input desired private key name: ')
pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
print('Generating Keys...')
primes = []
plist = []
for i in range(mp.cpu_count()):
plist.append(keysize)
workpool = mp.Pool(processes=mp.cpu_count())
reslist = workpool.imap_unordered(get1prime, plist)
workpool.close()
for res in reslist:
if res:
primes.append(res)
workpool.terminate()
break
workpool.join()
#
workpool1 = mp.Pool(processes=mp.cpu_count())
reslist = workpool1.imap_unordered(get1prime, plist)
workpool1.close()
for res in reslist:
if res:
primes.append(res)
workpool1.terminate()
break
workpool1.join()
if primes[0] != primes[1]:
p, q = primes[0], primes[1]
else:
print('Supremely Unlucky Try Again')
exit()
n = p*q
cm = lcm(p-1, q-1)
print('Computing Private key ...')
d = modInverse(e, cm)
print('Private Key Size: {} bits'.format(keysize*2))
print('Functional Length of: {}'.format(len(bin((d)))))
keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
with open(pkey, 'w') as f1:
f1.write(str(n)+'n')
f1.write(bytes.decode(keystring))
with open(pubkeyname, 'w') as f2:
f2.write(b64key)
print('Complete - {} and {} generated'.format(pubkeyname,pkey))
print('e exponent: {}'.format(str(e)))
print("""
-----BEGIN PUBLIC KEY-----
{}-----END PUBLIC KEY-----
""".format(b64key))
b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
print("""
-----BEGIN PRIVATE KEY-----
{}-----END PRIVATE KEY-----
""".format(b64privkey))

if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
os.system('gzip -9 {0};mv {0}.gz {0}'.format(workfile))
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0};mv {1} {1}.gz;gzip -d {1}'.format(outfile, workfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
os.system('mv {0} {0}.gz;gzip -d {0}.gz;rm {1}'.format(outfile, workfile))
print('Wrote out to {} '.format(outfile))





share|improve this answer










New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$



Here is the padded improved code from the suggestions here:



#!/usr/bin/env python3
import os
import sys
import math
import re
import hashlib
import random
import base64
import string
import getpass
import multiprocessing as mp
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2
#Non builtins
from gmpy2 import is_prime as isprime
from gmpy2 import is_strong_bpsw_prp as ispprime
#Primality testing, extended greatest common divisor and least common multiple

def get1prime(keysize):
while True:
p = random.randrange(1<<(keysize), 1<<(keysize+2))
if isprime(p):
if ispprime(p):
return p

def modInverse(a, m) : #Euclid's Extended Algorithm
m0 = m
y = 0
x = 1
while (a > 1) :
q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t
if (x < 0) :
x = x + m0
return x

def lcm(x, y):
return (x*y)//math.gcd(x,y)

##AES256CHUNK
def get_private_key(password):
salt = b"We will know, we must know"
kdf = PBKDF2(password, salt, 64, 1000)
key = kdf[:32]
return key

def encryptaes(raw, password):
private_key = password
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))

def decryptaes(enc, password):
private_key = password
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:]))

BLOCK_SIZE = 64 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537

def encryptit(e, n, thestring):#for sigining pass d as e
thestring = pad(str(thestring)).encode()
rbinlist = ['{0:08b}'.format(x) for x in thestring]
catstring = ''
catstring += rbinlist[0].lstrip('0')
del rbinlist[0]
for i in rbinlist:
catstring += str(i)
puttynumber = int(catstring,2)
cypherstring = str(pow(puttynumber, e, n))
return cypherstring

def decryptit(d, n, cynum):#for signing pass e as d
decryptmsg = ''
n = int(n)
d = int(d)
puttynum = pow(int(cynum), d, n)
puttynum = '{0:08b}'.format(puttynum)
while True:
if len(puttynum)%8 == 0:
break
puttynum = '0{0}'.format(puttynum)
locs = re.findall('[01]{8}', puttynum)
for x in locs:
letter = chr(int(x,2))
decryptmsg += letter
return unpad(decryptmsg)[2:-1]

#Begin User Flow
choice = input("""
██████╗ ██████╗ ██╗ ██╗██████╗ ████████╗
██╔════╝ ██╔══██╗╚██╗ ██╔╝██╔══██╗╚══██╔══╝
██║ ███╗██████╔╝ ╚████╔╝ ██████╔╝ ██║
██║ ██║██╔══██╗ ╚██╔╝ ██╔═══╝ ██║
╚██████╔╝██║ ██║ ██║ ██║ ██║
╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═
Welcome to Dan's Cryptography Concept Program.
Generate/Encrypt/Decrypt/Sign
RSA++/DSA++/AES/OTP/Double DH key exch w SHA
Choose:
A: Generate New Public/Private Key Pair
B: Encrypt a File
C: Decrypt a File
=> """)

if choice == 'A' or choice == 'a':
try:
keysize = (int(input("Enter a keysize: "))>>1)
except ValueError as a:
print('Enter a numbernn')
sys.exit()
pubkeyname = input('Input desired public key name: ')
pkey = input('Input desired private key name: ')
pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
print('Generating Keys...')
primes = []
plist = []
for i in range(mp.cpu_count()):
plist.append(keysize)
workpool = mp.Pool(processes=mp.cpu_count())
reslist = workpool.imap_unordered(get1prime, plist)
workpool.close()
for res in reslist:
if res:
primes.append(res)
workpool.terminate()
break
workpool.join()
#
workpool1 = mp.Pool(processes=mp.cpu_count())
reslist = workpool1.imap_unordered(get1prime, plist)
workpool1.close()
for res in reslist:
if res:
primes.append(res)
workpool1.terminate()
break
workpool1.join()
if primes[0] != primes[1]:
p, q = primes[0], primes[1]
else:
print('Supremely Unlucky Try Again')
exit()
n = p*q
cm = lcm(p-1, q-1)
print('Computing Private key ...')
d = modInverse(e, cm)
print('Private Key Size: {} bits'.format(keysize*2))
print('Functional Length of: {}'.format(len(bin((d)))))
keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
with open(pkey, 'w') as f1:
f1.write(str(n)+'n')
f1.write(bytes.decode(keystring))
with open(pubkeyname, 'w') as f2:
f2.write(b64key)
print('Complete - {} and {} generated'.format(pubkeyname,pkey))
print('e exponent: {}'.format(str(e)))
print("""
-----BEGIN PUBLIC KEY-----
{}-----END PUBLIC KEY-----
""".format(b64key))
b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
print("""
-----BEGIN PRIVATE KEY-----
{}-----END PRIVATE KEY-----
""".format(b64privkey))

if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
os.system('gzip -9 {0};mv {0}.gz {0}'.format(workfile))
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0};mv {1} {1}.gz;gzip -d {1}'.format(outfile, workfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
os.system('mv {0} {0}.gz;gzip -d {0}.gz;rm {1}'.format(outfile, workfile))
print('Wrote out to {} '.format(outfile))






share|improve this answer










New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this answer



share|improve this answer








edited yesterday





















New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









answered yesterday









dhoyt902dhoyt902

444




444




New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • $begingroup$
    This is a very good question and a nice tool. I suggest that you also try my suggestions as well. Your code is still hard to read. Lot more will benefit that way. :) You can also post this code or further edited code as another question so people will also review it.
    $endgroup$
    – 422_unprocessable_entity
    yesterday


















  • $begingroup$
    This is a very good question and a nice tool. I suggest that you also try my suggestions as well. Your code is still hard to read. Lot more will benefit that way. :) You can also post this code or further edited code as another question so people will also review it.
    $endgroup$
    – 422_unprocessable_entity
    yesterday
















$begingroup$
This is a very good question and a nice tool. I suggest that you also try my suggestions as well. Your code is still hard to read. Lot more will benefit that way. :) You can also post this code or further edited code as another question so people will also review it.
$endgroup$
– 422_unprocessable_entity
yesterday




$begingroup$
This is a very good question and a nice tool. I suggest that you also try my suggestions as well. Your code is still hard to read. Lot more will benefit that way. :) You can also post this code or further edited code as another question so people will also review it.
$endgroup$
– 422_unprocessable_entity
yesterday











0












$begingroup$

This is nice work. Very useful educational tool. Keep up the good work.



Now for some nitpicking:




def isprime(n):




  • This function has too much things going on in it. Can you break it to smaller functions by refactor extract function?



def isprime(n):
if not n & 1: #check if first bit is 1

#Fermat

#MilRab, x**2 = 1 mod P - ERH

def trial_composite(a):

for i in range(100): #Number of Rabin Witness




  • Every-time you have the urge to add comments like this it means there is something wrong. Extract functions.

  • Also if possible trial_composite should also go outside. But I can see this might not be possible.



def modInverse(a, m):
m0 = m




  • This function is really hard to understand. Please avoid using single letter variables. Rename them to something meaningful.

  • You are using a all over the place. I have no idea what it even means. Try to have meaningful parameters and variables.

  • Please add spaces before and after # comments.



BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537




  • Please define constants at the top so it's easier to read.

  • Why are you naming the lambda functions? Use a def if you want a name.

  • What is e here? name it properly so you don't need to comment.



modInverse




  • Please use snake_case to name functions. Why: Industry standard. PEP-8. You can use autopep8 or black to format your code.



if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
print('Wrote out to {} '.format(outfile))




  • Please don't jam your code together. You are not writing code in an A4 sheet.

  • Please add meaningful and logical separation.

  • This could also use some extract function refactoring.



os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))




  • Python already have shutil and gzip modules. They can move, copy files, folders and gzip stuff for you. It would be little more code, but your code can be easily made cross platform this way.






share|improve this answer











$endgroup$













  • $begingroup$
    Thank you 422!! This is great! I shall try to implement your suggestions - though the modular inverse will be hard to make clearer, its easier done on paper. I'll likely need to think for a bit on how to refactor certain bits, put I shall post the updated code either here or a new question.
    $endgroup$
    – dhoyt902
    yesterday










  • $begingroup$
    @dhoyt902 Create a new question titled Generate public/private keys, encrypt, decrypt, sign, verify v2.0 (You may also change v2.0 to something else you wish like for example follow-up). Plus asking a new question will give you more upvotes :)
    $endgroup$
    – 422_unprocessable_entity
    yesterday












  • $begingroup$
    @dhoyt902 Also added more info on how you can format code.
    $endgroup$
    – 422_unprocessable_entity
    yesterday
















0












$begingroup$

This is nice work. Very useful educational tool. Keep up the good work.



Now for some nitpicking:




def isprime(n):




  • This function has too much things going on in it. Can you break it to smaller functions by refactor extract function?



def isprime(n):
if not n & 1: #check if first bit is 1

#Fermat

#MilRab, x**2 = 1 mod P - ERH

def trial_composite(a):

for i in range(100): #Number of Rabin Witness




  • Every-time you have the urge to add comments like this it means there is something wrong. Extract functions.

  • Also if possible trial_composite should also go outside. But I can see this might not be possible.



def modInverse(a, m):
m0 = m




  • This function is really hard to understand. Please avoid using single letter variables. Rename them to something meaningful.

  • You are using a all over the place. I have no idea what it even means. Try to have meaningful parameters and variables.

  • Please add spaces before and after # comments.



BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537




  • Please define constants at the top so it's easier to read.

  • Why are you naming the lambda functions? Use a def if you want a name.

  • What is e here? name it properly so you don't need to comment.



modInverse




  • Please use snake_case to name functions. Why: Industry standard. PEP-8. You can use autopep8 or black to format your code.



if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
print('Wrote out to {} '.format(outfile))




  • Please don't jam your code together. You are not writing code in an A4 sheet.

  • Please add meaningful and logical separation.

  • This could also use some extract function refactoring.



os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))




  • Python already have shutil and gzip modules. They can move, copy files, folders and gzip stuff for you. It would be little more code, but your code can be easily made cross platform this way.






share|improve this answer











$endgroup$













  • $begingroup$
    Thank you 422!! This is great! I shall try to implement your suggestions - though the modular inverse will be hard to make clearer, its easier done on paper. I'll likely need to think for a bit on how to refactor certain bits, put I shall post the updated code either here or a new question.
    $endgroup$
    – dhoyt902
    yesterday










  • $begingroup$
    @dhoyt902 Create a new question titled Generate public/private keys, encrypt, decrypt, sign, verify v2.0 (You may also change v2.0 to something else you wish like for example follow-up). Plus asking a new question will give you more upvotes :)
    $endgroup$
    – 422_unprocessable_entity
    yesterday












  • $begingroup$
    @dhoyt902 Also added more info on how you can format code.
    $endgroup$
    – 422_unprocessable_entity
    yesterday














0












0








0





$begingroup$

This is nice work. Very useful educational tool. Keep up the good work.



Now for some nitpicking:




def isprime(n):




  • This function has too much things going on in it. Can you break it to smaller functions by refactor extract function?



def isprime(n):
if not n & 1: #check if first bit is 1

#Fermat

#MilRab, x**2 = 1 mod P - ERH

def trial_composite(a):

for i in range(100): #Number of Rabin Witness




  • Every-time you have the urge to add comments like this it means there is something wrong. Extract functions.

  • Also if possible trial_composite should also go outside. But I can see this might not be possible.



def modInverse(a, m):
m0 = m




  • This function is really hard to understand. Please avoid using single letter variables. Rename them to something meaningful.

  • You are using a all over the place. I have no idea what it even means. Try to have meaningful parameters and variables.

  • Please add spaces before and after # comments.



BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537




  • Please define constants at the top so it's easier to read.

  • Why are you naming the lambda functions? Use a def if you want a name.

  • What is e here? name it properly so you don't need to comment.



modInverse




  • Please use snake_case to name functions. Why: Industry standard. PEP-8. You can use autopep8 or black to format your code.



if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
print('Wrote out to {} '.format(outfile))




  • Please don't jam your code together. You are not writing code in an A4 sheet.

  • Please add meaningful and logical separation.

  • This could also use some extract function refactoring.



os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))




  • Python already have shutil and gzip modules. They can move, copy files, folders and gzip stuff for you. It would be little more code, but your code can be easily made cross platform this way.






share|improve this answer











$endgroup$



This is nice work. Very useful educational tool. Keep up the good work.



Now for some nitpicking:




def isprime(n):




  • This function has too much things going on in it. Can you break it to smaller functions by refactor extract function?



def isprime(n):
if not n & 1: #check if first bit is 1

#Fermat

#MilRab, x**2 = 1 mod P - ERH

def trial_composite(a):

for i in range(100): #Number of Rabin Witness




  • Every-time you have the urge to add comments like this it means there is something wrong. Extract functions.

  • Also if possible trial_composite should also go outside. But I can see this might not be possible.



def modInverse(a, m):
m0 = m




  • This function is really hard to understand. Please avoid using single letter variables. Rename them to something meaningful.

  • You are using a all over the place. I have no idea what it even means. Try to have meaningful parameters and variables.

  • Please add spaces before and after # comments.



BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537




  • Please define constants at the top so it's easier to read.

  • Why are you naming the lambda functions? Use a def if you want a name.

  • What is e here? name it properly so you don't need to comment.



modInverse




  • Please use snake_case to name functions. Why: Industry standard. PEP-8. You can use autopep8 or black to format your code.



if choice == 'B' or choice == 'b':
lineoutholder = []
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
print('Wrote out to {} '.format(outfile))




  • Please don't jam your code together. You are not writing code in an A4 sheet.

  • Please add meaningful and logical separation.

  • This could also use some extract function refactoring.



os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))




  • Python already have shutil and gzip modules. They can move, copy files, folders and gzip stuff for you. It would be little more code, but your code can be easily made cross platform this way.







share|improve this answer














share|improve this answer



share|improve this answer








edited yesterday

























answered yesterday









422_unprocessable_entity422_unprocessable_entity

2,09831751




2,09831751












  • $begingroup$
    Thank you 422!! This is great! I shall try to implement your suggestions - though the modular inverse will be hard to make clearer, its easier done on paper. I'll likely need to think for a bit on how to refactor certain bits, put I shall post the updated code either here or a new question.
    $endgroup$
    – dhoyt902
    yesterday










  • $begingroup$
    @dhoyt902 Create a new question titled Generate public/private keys, encrypt, decrypt, sign, verify v2.0 (You may also change v2.0 to something else you wish like for example follow-up). Plus asking a new question will give you more upvotes :)
    $endgroup$
    – 422_unprocessable_entity
    yesterday












  • $begingroup$
    @dhoyt902 Also added more info on how you can format code.
    $endgroup$
    – 422_unprocessable_entity
    yesterday


















  • $begingroup$
    Thank you 422!! This is great! I shall try to implement your suggestions - though the modular inverse will be hard to make clearer, its easier done on paper. I'll likely need to think for a bit on how to refactor certain bits, put I shall post the updated code either here or a new question.
    $endgroup$
    – dhoyt902
    yesterday










  • $begingroup$
    @dhoyt902 Create a new question titled Generate public/private keys, encrypt, decrypt, sign, verify v2.0 (You may also change v2.0 to something else you wish like for example follow-up). Plus asking a new question will give you more upvotes :)
    $endgroup$
    – 422_unprocessable_entity
    yesterday












  • $begingroup$
    @dhoyt902 Also added more info on how you can format code.
    $endgroup$
    – 422_unprocessable_entity
    yesterday
















$begingroup$
Thank you 422!! This is great! I shall try to implement your suggestions - though the modular inverse will be hard to make clearer, its easier done on paper. I'll likely need to think for a bit on how to refactor certain bits, put I shall post the updated code either here or a new question.
$endgroup$
– dhoyt902
yesterday




$begingroup$
Thank you 422!! This is great! I shall try to implement your suggestions - though the modular inverse will be hard to make clearer, its easier done on paper. I'll likely need to think for a bit on how to refactor certain bits, put I shall post the updated code either here or a new question.
$endgroup$
– dhoyt902
yesterday












$begingroup$
@dhoyt902 Create a new question titled Generate public/private keys, encrypt, decrypt, sign, verify v2.0 (You may also change v2.0 to something else you wish like for example follow-up). Plus asking a new question will give you more upvotes :)
$endgroup$
– 422_unprocessable_entity
yesterday






$begingroup$
@dhoyt902 Create a new question titled Generate public/private keys, encrypt, decrypt, sign, verify v2.0 (You may also change v2.0 to something else you wish like for example follow-up). Plus asking a new question will give you more upvotes :)
$endgroup$
– 422_unprocessable_entity
yesterday














$begingroup$
@dhoyt902 Also added more info on how you can format code.
$endgroup$
– 422_unprocessable_entity
yesterday




$begingroup$
@dhoyt902 Also added more info on how you can format code.
$endgroup$
– 422_unprocessable_entity
yesterday










dhoyt902 is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















dhoyt902 is a new contributor. Be nice, and check out our Code of Conduct.













dhoyt902 is a new contributor. Be nice, and check out our Code of Conduct.












dhoyt902 is a new contributor. Be nice, and check out our Code of Conduct.
















Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214375%2fgenerate-public-private-keys-encrypt-decrypt-sign-verify%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

is 'sed' thread safeWhat should someone know about using Python scripts in the shell?Nexenta bash script uses...

How do i solve the “ No module named 'mlxtend' ” issue on Jupyter?

Pilgersdorf Inhaltsverzeichnis Geografie | Geschichte | Bevölkerungsentwicklung | Politik | Kultur...