Python RSA encryption errors - python

I'm trying to create a simple version of RSA in Python, but - whether it is due to the limitations of Python integers or my awful code - it is not returning the same decrypted message as the original. My key generator does seem to create valid keys, so I am curious as to how it is failing.
Attached is the code I used - I thought it was short enough to not need to add a stub.
from random import randint
from math import sqrt, ceil
#This is the private key the bank uses
bankPrime = 6619319052850372576671203008980947142174030778088896832879139788043990604607
#This is the public key
clientPrime = 89981040860183284202926925086489690550566335265876097787978356913003610730551
#Calculate modulus
modulus = bankPrime * clientPrime
#Calculate totient of modulus
totient = (bankPrime - 1)*(clientPrime - 1)
#Creates random numbers until it passes Euclid's algorithm with the GCD being 1 - coprime generator
def xgcd(b, n):
x0, x1, y0, y1 = 1, 0, 0, 1
while n != 0:
q, b, n = b // n, n, b % n
x0, x1 = x1, x0 - q * x1
y0, y1 = y1, y0 - q * y1
return b, x0
while True:
pubkeyexponent = randint(3, ceil(sqrt(totient)))
gcd, prikeyexponent = xgcd(pubkeyexponent, totient)
if prikeyexponent < 0:
prikeyexponent += totient
if gcd == 1:
break
print("Totient n", totient)
print("Private Key d", prikeyexponent)
print("Public Key e", pubkeyexponent)
print("Modulus", modulus)
print()
print("Type the message you want to encrypt:")
message = input(">:")
encrypted = 0
for x in range(len(message)):
encrypted += (256**x) * ord(message[x])
print(encrypted)
networkmessage = pow(encrypted, pubkeyexponent, totient)
print("The number message sent over the network to the bank is this:", networkmessage)
encrypted = pow(networkmessage, prikeyexponent, totient)
print("The number message sent back to the client is this:", encrypted)

You could use cryptographer
This code will encrypt, decrypt, save RSA keys to a file, and load them back again.
from cryptographer import RSAKey()
key = RSAKey()
encrypted = key.encrypt('Hello World') # also works with bytes data
print('Encrypted Text:', encrypted)
decrypted = key.decrypt(encrypted)
print('Decrypted Text:', decrypted)
# Save key to file
import pickle
pickle.dump(rsa, open('rsa.dat', 'wb')
# Load key from file
old_rsa = rsa
rsa = pickle.load(open('rsa.dat', 'rb'))
print(rsa == old_rsa) # True

Related

Python decimal.InvalidOperation Error Using A Large Number

In python, I wrote a program to work out the value of pi using the Chudnovsky Algorithm. It works on numbers under 800. However, if I use a number above 800, it returns a decimal.InvalidOperation error. This is my code:
from math import factorial
from decimal import Decimal, getcontext
getcontext().prec = 1000
pi_input = input("How Many Digits Of Pi Are To Be Represented: ")
num = int(pi_input)
def cal(n):
t = Decimal(0)
pi = Decimal(0)
deno = Decimal(0)
for k in range(n):
t = ((-1) ** k) * (factorial(6 * k)) * (13591409 + 545140134 * k)
deno = factorial(3 * k) * (factorial(k) ** 3) * (640320 ** (3 * k))
pi += Decimal(t) / Decimal(deno)
pi = pi * Decimal(12) / Decimal(640320 ** Decimal(1.5))
pi = 1 / pi
return round(pi, n)
print(cal(num))
Could Anyone Please Help Me?
I wouldn't recommend your method. Try using the gmpy module like this:
import sys
import math
import os.path
from gmpy2 import mpz, sqrt
from time import time, sleep
print_pi = input("Should The Value Of Pi Be Printed: ").lower()
print_pi_bool = 0
if "y" in print_pi:
print_pi_bool = True
elif "n" in print_pi:
print_pi = False
else:
print("Incorrect Input. Please Try Again.")
sys.exit()
def sqrt(n, one):
"""
Return the square root of n as a fixed point number with the one
passed in. It uses a second order Newton-Raphson convgence. This
doubles the number of significant figures on each iteration.
"""
# Use floating point arithmetic to make an initial guess
floating_point_precision = 10**16
n_float = float((n * floating_point_precision) // one) / floating_point_precision
x = (int(floating_point_precision * math.sqrt(n_float)) * one) // floating_point_precision
n_one = n * one
count = 0
while 1:
count += 1
print(count)
x_old = x
x = (x + n_one // x) // 2
if x == x_old:
break
return x
def pi_chudnovsky_bs(digits):
"""
Compute int(pi * 10**digits)
This is done using Chudnovsky's series with binary splitting
"""
C = 640320
C3_OVER_24 = C**3 // 24
def bs(a, b):
"""
Computes the terms for binary splitting the Chudnovsky infinite series
a(a) = +/- (13591409 + 545140134*a)
p(a) = (6*a-5)*(2*a-1)*(6*a-1)
b(a) = 1
q(a) = a*a*a*C3_OVER_24
returns P(a,b), Q(a,b) and T(a,b)
"""
if b - a == 1:
# Directly compute P(a,a+1), Q(a,a+1) and T(a,a+1)
if a == 0:
Pab = Qab = mpz(1)
else:
Pab = mpz((6*a-5)*(2*a-1)*(6*a-1))
Qab = mpz(a*a*a*C3_OVER_24)
Tab = Pab * (13591409 + 545140134*a) # a(a) * p(a)
if a & 1:
Tab = -Tab
else:
# Recursively compute P(a,b), Q(a,b) and T(a,b)
# m is the midpoint of a and b
m = (a + b) // 2
# Recursively calculate P(a,m), Q(a,m) and T(a,m)
Pam, Qam, Tam = bs(a, m)
# Recursively calculate P(m,b), Q(m,b) and T(m,b)
Pmb, Qmb, Tmb = bs(m, b)
# Now combine
Pab = Pam * Pmb
Qab = Qam * Qmb
Tab = Qmb * Tam + Pam * Tmb
return Pab, Qab, Tab
# how many terms to compute
DIGITS_PER_TERM = math.log10(C3_OVER_24/6/2/6)
N = int(digits/DIGITS_PER_TERM + 1)
# Calclate P(0,N) and Q(0,N)
P, Q, T = bs(0, N)
one_squared = mpz(10)**(2*digits)
sqrtC = sqrt(10005*one_squared, one_squared)
return (Q*426880*sqrtC) // T
# The last 5 digits or pi for various numbers of digits
check_digits = {
100 : 70679,
1000 : 1989,
10000 : 75678,
100000 : 24646,
1000000 : 58151,
10000000 : 55897,
}
if __name__ == "__main__":
digits = 100
pi = pi_chudnovsky_bs(digits)
#raise SystemExit
for log10_digits in range(1,11):
digits = 10**log10_digits
start =time()
pi = pi_chudnovsky_bs(digits)
pi = str(pi)
pi = pi[:(len(str(pi)) // 2) + 1]
length = int(len(str(pi))) - 1
print("Chudnovsky Binary Splitting Using GMPY: Digits",f"{digits:,}","\n--------------",time()-start,"--------------")
print("Length Of " + f"{length:,}" + " Digits")
It's my first answer, so I hope it helps!

Recursive Decryption of String with AES-256-cbc

I am trying to decrypt an AES CBC string for the number of times it was decrypted.
I was successful in decrypting the first time.
from Crypto.Cipher import AES
k = '57067125438768260656188878670043'
key = bytes(k, 'ascii')
i = '5706712543876826'
iv = bytes(i, 'ascii')
dec = AES.new(key, AES.MODE_CBC, iv)
n = 2
cipher = 'dd3364461dbca39ddb5eb32e9f11b81f000acac9ce8b91369f8bf7e4a88787785a8cc498c85ea20370e68f0e7014e92a2b5aedd4c670ec172d7adb45dfa5a770b582e8ed255bb857d94afdfd6e579525f24890070f984b8862133eda9cbb118ba7880db125c32dea7e7c54bc77abfc02'
def unpad(s):
return s[:-ord(s[len(s)-1:])]
def decrypt(cipherId):
cipher = bytes.fromhex(cipherId)
id = dec.decrypt(cipher)
node_dec = unpad(id.decode('utf-8'))
print (node_dec)
return node_dec
that is the first stage of encryption, but I don't know how to set a loop to run the function again based on n. this cipher for example was encrypted twice, it might be three or four or more.
I created another function to decrypt the output of the decrypt function because the output gives a different codec.
def decrypt_again(cipherId):
cipher = bytes.fromhex(cipherId)
id = dec.decrypt(cipher)
node_dec = unpad(id.decode('ISO-8859-1'))
print (node_dec)
return node_dec
so I tried writing this loop
x = decrypt(cipher)
for i in range (n):
y = decrypt_again(x)
but it only works for n = 1, if n is more than 1, it just keeps repeating y instead of parsing it again.
how can I go about it, please?
also if I re-run the function twice something happens to the string, I get ó³*Ä'»g)X»#¾ú84-8089-be57330fcd45 instead of this a214868d-f40b-4184-8089-be57330fcd45, there seem to be a break in the codec
any reason why this is so?
every time it sets y to decrypt_again(x), x is still the same so you should add a line that sets x to y so it remembers the result of the previous iteration
x = decrypt(cipher)
for i in range (n):
y = decrypt_again(x)
x = y
so guys I was able to solve the issue. here is the correct code that works top-notch.
from Crypto.Cipher import AES
k = '57067125438768260656188878670043'
key = bytes(k, 'ascii')
i = '5706712543876826'
iv = bytes(i, 'ascii')
n = 4
cipher = 'afc6f435d3bb68234bba2d39840d4c61cd0d45810940cf796ebf4078e1c0b2368caf618dd6c915fa3f9e0245372cc0dd9992d71aa3ac9e811a579a1d39fa9e26b0d1728d290f4bfa54931917afb45c49a815937498923e241a3eded50dff67ff18d9c1259404f1bdbafef7df5aba0c0b2aacc18079b6bb64058a7976246c0231b2178312c9a008dfa3bd954eef12c73d0b3adac8aa2f4733fe09767dc08741997a6243642d7a5fc627eede9fbeea9f9d931f90daa1cc6a760e352a36d55f22ea1a8bb4bd993d96f4cd006ad9de128d7ea9cd74b875ac2c55e62905b67eb354b5bac48961940fbdc1c0dc58ebc3b7356cb95c11505c8d9bbecc8670d7327ed5fcffd3577ed7d87adf628c5b44cb92c1e33f66715d2d429d3a62dc88a80fc3a3b4a720e9680b4ff444d4e87057a7fbe66afba6bffd96b641bfb03c0802528e30768c5695db92d0dd4f4db3d5301c17ed37accbe3c89d2c70d4fbb3e40d30164b640154fa9ecd5565b11af24f40fe91fbca3966ce1632a3dbbd6c1af432b2100a9f7136834fc00609170b6cf66a3861bf9aa1902292152ba6efdefeacc4d4d37e20896a42243f3ec2f4ae463cfa455e92d4df33688cb127ade64dbad056b1614fe2f2a32b0b2536a23f4b019511df378778c374413629e7afe83a047fe6745de19397193e7082f8ab27b4b41695f43abd9c'
def unpad(s):
return s[:-ord(s[len(s)-1:])]
def decrypt(cipherId):
dec = AES.new(key, AES.MODE_CBC, iv)
cipher = bytes.fromhex(cipherId)
id = dec.decrypt(cipher)
node_dec = unpad(id.decode('ISO-8859-1'))
return node_dec
if __name__ == '__main__':
x = decrypt(cipher)
result = ""
for i in range(n - 1):
y = decrypt(x)
x = y
result = x
print(result)

How to implement HMAC in python without using the hmac library?

I want to implement the hmac algorithm with SHA-1 by the definition from RFC 2104. The code is running but the results aren't the same as the test-vectors from RFC. I'm not sure if I'm loading the values correctly(String to Hex, or String to Bytes?).
As template I've used the pseudo-code from wikipedia
I'm not sure about the terms 'blocksize' and 'output size'. In the code from wikipedia the outputsize is one of the input values but never used.
This is my code so far:
First I'm setting up a hash-function, then I'm converting my input-strings (key and message) into hex values. Next step is to to look if key hast go get hashed or filled with zeros. Next I'm xor-ing the single chars from the key with those values (I don't know where they come from, but they're in every example without any comment). Last but not least I'm combining an inner string(I_key_pad + message) and hash it which results in an outer strings that im combining with the outer pad and hash it again.
import hashlib
from functools import reduce
def hmac(key, message, hashfunc):
hasher = hashlib.sha1
blocksize = 40
message = toHex(message) #is this right?
key = toHex(key)
#alternative: loading values as bytes
#message = bytes(message, 'utf-8')
#key = bytes(key, 'utf-8')
if len(key) > blocksize:
key = hasher(key)
else:
#key = key.ljust(blocksize, '0') #filling from right to left
#key = key.ljust(blocksize, b'\0') #same as above but for bytes
key = pad(key, blocksize) #filling from left to right
val1 = 0x5c
val2 = 0x36
i = 0
o_key_pad = ""
i_key_pad = ""
while i < blocksize:
o_key_pad += str(ord(key[i]) ^ val1)
i_key_pad += str(ord(key[i]) ^ val2)
i += 1
tmp_string = str(i_key_pad) + str(message)
tmp_string = tmp_string.encode()
inner_hash = hasher(tmp_string).hexdigest()
fullstring = str(o_key_pad) + inner_hash
fullstring = fullstring.encode()
fullstring = hasher(fullstring).hexdigest()
print(fullstring)
def pad(key, blocksize):
key = str(key)
while len(key) < blocksize:
key = '0' + key
key = key
return key
def toHex(s):
lst = []
for ch in s:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0' + hv
lst.append(hv)
return reduce(lambda x, y: x + y, lst)
def main():
while (1):
key = input("key = ")
message = input("message = ")
hash = input("hash (0: SHA-256, 1: SHA-1) = ")
hmac(key, message, hash)
if __name__ == "__main__":
main()
I'm not understanding all the steps in your code, but here's a short example showing HMAC-SHA1 using only hashlib.sha1, with a helper function xor.
import hashlib
def xor(x, y):
return bytes(x[i] ^ y[i] for i in range(min(len(x), len(y))))
def hmac_sha1(key_K, data):
if len(key_K) > 64:
raise ValueError('The key must be <= 64 bytes in length')
padded_K = key_K + b'\x00' * (64 - len(key_K))
ipad = b'\x36' * 64
opad = b'\x5c' * 64
h_inner = hashlib.sha1(xor(padded_K, ipad))
h_inner.update(data)
h_outer = hashlib.sha1(xor(padded_K, opad))
h_outer.update(h_inner.digest())
return h_outer.digest()
def do_tests():
# test 1
k = b'\x0b' * 20
data = b"Hi There"
result = hmac_sha1(k, data)
print(result.hex())
# add tests as desired

Python 3: ValueError: invalid literal for int() with base 10: '0001.0110010110010102e+22'

I'm a beginner, so sorry if this is obvious.
I'm at a loss here. I've been trying to make an encryption/decryption program, but I keep getting this error. I'm aware that there are other questions on this issue, but I still can't resolve it.
Encryptor:
import binascii
def text_to_bits(text, encoding='utf-8', errors='surrogatepass'):
bits = bin(int(binascii.hexlify(text.encode(encoding, errors)), 16))[2:]
return bits.zfill(8 * ((len(bits) + 7) // 8))
def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'):
n = int(bits, 2)
return int2bytes(n).decode(encoding, errors)
def int2bytes(i):
hex_string = '%x' % i
n = len(hex_string)
return binascii.unhexlify(hex_string.zfill(n + (n & 1)))
#ENCRYPTION ALGORITHM
algorithm = 61913299
#ASCII ----> NUMBERS
raw = input("Enter text to encrypt:")
binary = text_to_bits(raw)
binary = int(binary)
algorithm = int(algorithm)
encrypted = binary * algorithm
encrypted = str(encrypted)
print(encrypted)
print("Done")
Decryptor:
import sys
import time
def to_bin(string):
res = ''
for char in string:
tmp = bin(ord(char))[2:]
tmp = '%08d' %int(tmp)
res += tmp
return res
def to_str(string):
res = ''
for idx in range(len(string)/8):
tmp = chr(int(string[idx*8:(idx+1)*8], 2))
res += tmp
return res
incorrectpasswords = 0
password=("password")
originpassword = password
x = 1
algorithm = 61913299
while x==1:
passwordattempt =input("Enter Password:")
if passwordattempt == password:
print("Correct")
x = 2
if passwordattempt!= password:
print("Incorrect")
incorrectpasswords = incorrectpasswords + 1
if incorrectpasswords > 2:
if x == 1:
print("Too many wrong attempts, please try again in one minute.")
time.sleep(60)
encrypted = input("Enter numbers to unencrypt:")
encrypted = int(encrypted)
one = encrypted / algorithm
size = sys.getsizeof(one)
one = str(one).zfill(size + 1)
one = int(one)
unencrypted = to_str(one)
x = unencrypted
For the conversion between binary and text, and text and binary, I used some code I found online.
I believe your code is not working because:
one = encrypted / algorithm
generates a float
to turn your string back into a number you should apply
eval(one)
or
float(one)
instead of
int(one)
(You can also turn it into an int after applying float or eval)
alternatively you might be able to get it by using integer division // as opposed to / , which will make one the type int by flooring the decimal result of the divison, but I'm not sure if that is the behavior you are looking for
Example in python 3 shell:
>>> import sys
>>> one = 15/25
>>> size = sys.getsizeof(one)
>>> one = str(one).zfill(size+1)
>>> one
'00000000000000000000000.6'
>>> type(one)
<class 'str'>
>>> one = eval(one)
>>> one
0.6
>>> type(one)
<class 'float'>

RC4 decryption in python hexadecimal inputs

I have a program that successfully encrypts a piece of plain text information and outputs the encrypted data as hexadecimal. i can decrypt this data on http://www.fyneworks.com/encryption/rc4-encryption/index.asp by putting in the hex data i received from my program and the key i used (in plain text)
the next step i am trying to accomplish is to have two inputs where i can input an encrypted message in hex and the encryption key (also in hex).
i'm having trouble getting the decryption part of my program to work...
If i enter the key as password and the ciphertext as 8c905b7c294a94c30422d81d552e which successfully decrypts on the website above... it doesn't work.
anyone have any ideas how i can get decryption working in RC4 with hexadecimal inputs?
# Global variables
state = [None] * 256
p = q = None
def setKey(key):
##RC4 Key Scheduling Algorithm (KSA)
global p, q, state
state = [n for n in range(256)]
p = q = j = 0
for i in range(256):
if len(key) > 0:
j = (j + state[i] + key[i % len(key)]) % 256
else:
j = (j + state[i]) % 256
state[i], state[j] = state[j], state[i]
def byteGenerator():
##RC4 Pseudo-Random Generation Algorithm (PRGA)
global p, q, state
p = (p + 1) % 256
q = (q + state[p]) % 256
state[p], state[q] = state[q], state[p]
return state[(state[p] + state[q]) % 256]
def encrypt(key,inputString):
##Encrypt input string returning a byte list
setKey(string_to_list(key))
return [ord(p) ^ byteGenerator() for p in inputString]
def decrypt(inputByteList):
##Decrypt input byte list returning a string
return "".join([chr(c ^ byteGenerator()) for c in inputByteList])
def intToList(inputNumber):
##Convert a number into a byte list
inputString = "{:02x}".format(inputNumber)
return [int(inputString[i:i + 2], 16) for i in range(0, len(inputString), 2)]
def string_to_list(inputString):
##Convert a string into a byte list
return [ord(c) for c in inputString]
key = raw_input("Enter Key: ")
ciphertext = raw_input("enter ciphertext: ")
print decrypt(intToList(ciphertext))
Here is general idea of how encryption / decryption can be done using reference implementation of RC4 for python:
def KSA(key):
keylength = len(key)
S = range(256)
j = 0
for i in range(256):
j = (j + S[i] + key[i % keylength]) % 256
S[i], S[j] = S[j], S[i] # swap
return S
def PRGA(S):
i = 0
j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # swap
K = S[(S[i] + S[j]) % 256]
yield K
def RC4(key):
S = KSA(key)
return PRGA(S)
if __name__ == '__main__':
# ciphertext should be 9D5AB375EC
key = 'secret'
plaintext = 'plain'
def convert_key(s):
return [ord(c) for c in s]
key = convert_key(key)
keystream = RC4(key)
ciphertext = ''.join([("%02X" % (ord(c) ^ keystream.next())) for c in plaintext])
print ciphertext
keystream = RC4(key)
def convert_ct(s):
import binascii
return [ord(ch) for ch in binascii.unhexlify(s)]
ciphertext = convert_ct(ciphertext)
plaintext = ''.join([chr(c ^ keystream.next()) for c in ciphertext])
print plaintext
With your code base it can be done like so:
import binascii
# Global variables
state = [None] * 256
p = q = None
def setKey(key):
##RC4 Key Scheduling Algorithm (KSA)
global p, q, state
state = [n for n in range(256)]
p = q = j = 0
for i in range(256):
if len(key) > 0:
j = (j + state[i] + key[i % len(key)]) % 256
else:
j = (j + state[i]) % 256
state[i], state[j] = state[j], state[i]
def byteGenerator():
##RC4 Pseudo-Random Generation Algorithm (PRGA)
global p, q, state
p = (p + 1) % 256
q = (q + state[p]) % 256
state[p], state[q] = state[q], state[p]
return state[(state[p] + state[q]) % 256]
def encrypt(key, plaintext):
##Encrypt input string returning a byte list
pt = string_to_list(plaintext)
ct = rc4(key, pt)
return list_to_string(ct, hex=True)
def decrypt(key, ciphertext):
##Decrypt input byte list returning a string
ct = string_to_list(ciphertext, hex=True)
pt = rc4(key, ct)
return list_to_string(pt, hex=False)
def string_to_list(input_srt, hex=False):
##Convert a string into an int list
if hex:
res = [ord(ch) for ch in binascii.unhexlify(input_srt)]
else:
res = [ord(ch) for ch in input_srt]
return res
def list_to_string(lst, hex=True):
##Convert an int list into a string
if hex:
res = ''.join(["%0.2X" % el for el in lst])
else:
res = ''.join([chr(el) for el in lst])
return res
def rc4(key, ints):
"""Xor list of ints with output generated by RC4. Output list of ints"""
setKey(string_to_list(key))
return [x ^ byteGenerator() for x in ints]
# key = raw_input("Enter Key: ")
# ciphertext = raw_input("enter ciphertext: ")
key = 'secret'
plaintext = 'plain'
ciphertext = encrypt(key, plaintext)
print ciphertext
print decrypt(key, ciphertext)
Decryption and encryption are basically the same procedures

Categories

Resources