Generate public/private keys, encrypt, decrypt, sign, verify
$begingroup$
My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk for speed. 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'm using this as an educational tool force the unwilling 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's
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 cryptography
New contributor
$endgroup$
add a comment |
$begingroup$
My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk for speed. 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'm using this as an educational tool force the unwilling 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's
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 cryptography
New contributor
$endgroup$
add a comment |
$begingroup$
My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk for speed. 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'm using this as an educational tool force the unwilling 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's
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 cryptography
New contributor
$endgroup$
My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk for speed. 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'm using this as an educational tool force the unwilling 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's
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 cryptography
python cryptography
New contributor
New contributor
edited 3 mins ago
Jamal♦
30.3k11119227
30.3k11119227
New contributor
asked 14 mins ago
dhoyt902dhoyt902
11
11
New contributor
New contributor
add a comment |
add a comment |
0
active
oldest
votes
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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