How to Encrypt and UnEncrypt text in Python [duplicate] - python

This question already has answers here:
How do I encrypt and decrypt a string in python?
(10 answers)
Closed 6 years ago.
I was wondering if I could encrypt a raw data so for example:
message = encrypt(raw_input("what is your message")) <---- I want this encrypted
Then in my server code, I want it unencrypted:
print unencrypt(str(message)) <----- I want this
I want it similar to this. How can I do it on Python 2.7?

You can use following Code:
import base64
def encode(key, clear):
enc = []
for i in range(len(clear)):
key_c = key[i % len(key)]
enc_c = chr((ord(clear[i]) + ord(key_c)) % 256)
enc.append(enc_c)
return base64.urlsafe_b64encode("".join(enc))
def decode(key, enc):
dec = []
enc = base64.urlsafe_b64decode(enc)
for i in range(len(enc)):
key_c = key[i % len(key)]
dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256)
dec.append(dec_c)
return "".join(dec)
encoded_string=encode('password','text text')
print encoded_string
decoded_string=decode('password',encoded_string)
print decoded_string

Related

Vigenere Cipher Decryption Issues

key = "password"
def cipher(text): #my example cipher method
encoded_chars = []
for i in range(len(text)):
key_c = key[i % len(key)]
encoded_c = chr(ord(text[i]) + ord(key_c) % 256)
encoded_chars.append(encoded_c)
encoded_string = ''.join(encoded_chars)
return (encoded_string)
def decipher(text):
dec = []
text = base64.urlsafe_b64encode(b"'{text}'").decode()
print('text')
for i in range(len(text)):
key_c = key[i % len(key)]
dec_c = chr((256 + ord(text[i]) - ord(key_c)) % 256)
dec.append(text)
return str(dec_c)
enter code here
print(decipher("test"))
After encrypting it successfully with vigenere cipher I get something like this: b'\xc2\xbd\xc2\xb8\xc3\x83\xc3\x80'
I would like to decrypt this string with the code above and turn it into back to the text "password" however when I try to decrypt my text it leaves me with another encoded string. Can someone explain what I am doing wrong with my decryption?
It's not clear what you are trying to do with the base64 library. Also, you are mixing up come variables in your decrypt method:
dec.append(text) # text is the passed in argument.
# Why append it to the result
return str(dec_c) # this is the last element in the loop
# why return this rather than the list you made above?
Neither of the above things make much sense. Maybe something like this will get it going in the right direction:
key = "password"
def cipher(text): #my example cipher method
encoded_chars = []
for i in range(len(text)):
key_c = key[i % len(key)]
encoded_c = chr(ord(text[i]) + ord(key_c) % 256)
encoded_chars.append(encoded_c)
encoded_string = ''.join(encoded_chars)
return (encoded_string)
def decipher(text):
dec = []
for i in range(len(text)):
key_c = key[i % len(key)]
dec_c = chr((256 + ord(text[i]) - ord(key_c)) % 256)
dec.append(dec_c)
return "".join(dec)
plain = "some text to encrypt"
encrypted = cipher(plain)
print("encrypted: ", encrypted)
decrypted = decipher(encrypted)
print("decrypted: ", decrypted)
Prints:
encrypted: ãÐàØã×ÜäçâÔàÇâÚãç
decrypted: some text to encrypt

Python2 version of this python3 code for encoding

I am trying to run code from the answer in this post (which works perfectly with python3 version 3.5.3) with python2 version 2.7.13:
def myencode_str(ori_str, key):
enc = []
for i in range(len(ori_str)):
key_c = key[i % len(key)]
enc_c = (ord(ori_str[i]) + ord(key_c)) % 256
enc.append(enc_c)
return (base64.urlsafe_b64encode(bytes(enc))).decode("utf-8")
I am using following decode fn:
def mydecode(enc_str, key):
dec = []
enc_str = base64.urlsafe_b64decode(enc_str)
for i in range(len(enc_str)):
key_c = key[i % len(key)]
dec_c = chr((256 + enc_str[i] - ord(key_c)) % 256)
dec.append(dec_c)
return "".join(dec)
But I get following error message:
dec_c = chr((256 + enc_str[i] - ord(key_c)) % 256)
TypeError: unsupported operand type(s) for +: 'int' and 'str'
I tried code with following changes but they also do not work:
dec_c = chr((256 + int(enc_str[i]) - int(ord(key_c))) % 256)
ValueError: invalid literal for int() with base 10: '\xc3'
Where is the problem and how can it be solved?
The problems is that bytes constructor has changed between Python2 and Python3, when it receives an list of integers:
in Python3, it builds a byte string where each byte receives a code from the list
in Python2, it just converts the list to a string (by using the representation or the string)
And in Python3 a byte string is an iterable of bytes (which are directly convertible to integers) while it is a mere string in Python2.
So your functions have to be a little changed:
def myencode_str(ori_str, key):
enc = []
for i in range(len(ori_str)):
key_c = key[i % len(key)]
enc_c = (ord(ori_str[i]) + ord(key_c)) % 256
enc.append(enc_c)
return (base64.urlsafe_b64encode(''.join([chr(i) for i in enc])))
def mydecode(enc_str, key):
dec = []
enc_str = [ord(i) for i in base64.urlsafe_b64decode(enc_str)]
for i in range(len(enc_str)):
key_c = key[i % len(key)]
dec_c = chr((256 + enc_str[i] - ord(key_c)) % 256)
dec.append(dec_c)
return "".join(dec)
In fact, it is possible to write those functions so that same code can be used in both Python2 and Python3 with the help of the bytearray class which has same behaviour in both versions. Simply you must choose whether the input is a byte string or a unicode string. As the algorythm is based on bytes, I choosed to process byte strings in following code. You would need to encode the original string and key (using 'utf8' for full portability) and decode the decoded string to process unicode strings:
def myencode_str(ori_str, key):
enc = []
b = bytearray(ori_str)
k = bytearray(key)
for i, c in enumerate(b):
key_c = k[i % len(key)]
enc_c = (c + key_c) % 256
enc.append(enc_c)
return (base64.urlsafe_b64encode(bytes(bytearray(enc))))
def mydecode(enc_str, key):
dec = []
enc_str = bytearray(base64.urlsafe_b64decode(enc_str))
k = bytearray(key)
for i, c in enumerate(enc_str):
key_c = k[i % len(key)]
dec_c = (c - key_c) % 256
dec.append(dec_c)
return bytes(bytearray(dec))
You can then do in Python2:
>>> myencode_str(b"abcdef", b"XYZ")
'ubu9vL7A'
>>> mydecode('ubu9vL7A', b"XYZ")
'abcdef'
and in Python3:
>>> myencode_str(b"abcdef", b"XYZ")
b'ubu9vL7A'
>>> mydecode(b'ubu9vL7A', b"XYZ")
b'abcdef'

AES-CBC 128, 192 and 256 encryption decryption in Python 3 using PKCS#7 padding

I have searched a lot on SO about complete encryption decryption example with my requirement. In fact, I've got many links and examples but None is working for me for AES-192-CBC mode and AES-256-CBC.
I have got following example which is supposed to be working with all types but it is working only with AES-128-CBC mode. I am new to Python. Can anyone help me where I am wrong?
I am using Python 3.4 on windows and I can not move to Python 2.7.
import base64
from Crypto.Cipher import AES
class AESCipher:
class InvalidBlockSizeError(Exception):
"""Raised for invalid block sizes"""
pass
def __init__(self, key, block_size=16):
if block_size < 2 or block_size > 255:
raise AESCipher.InvalidBlockSizeError('The block size must be between 2 and 255, inclusive')
self.block_size = block_size
self.key = key
self.iv = bytes(key[0:16], 'utf-8')
print(self.key)
print(key[0:16])
def __pad(self, text):
text_length = len(text)
amount_to_pad = self.block_size - (text_length % self.block_size)
if amount_to_pad == 0:
amount_to_pad = self.block_size
self.pad = chr(amount_to_pad)
return text + self.pad * amount_to_pad
def __unpad(self, text):
#pad = ord(text[-1])
#return text[:-pad]
text = text.rstrip(self.pad)
return text
def encrypt( self, raw ):
raw = self.__pad(raw)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
return base64.b64encode(cipher.encrypt(raw))
def decrypt( self, enc ):
enc = base64.b64decode(enc)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv )
return self.__unpad(cipher.decrypt(enc).decode("utf-8"))
e = AESCipher('1234567812345678', 16)
#e = AESCipher('123456781234567812345678', 24)
#e = AESCipher('12345678123456781234567812345678', 32)
secret_data = "hi"
enc_str = e.encrypt(secret_data)
print('enc_str: ' + enc_str.decode())
dec_str = e.decrypt(enc_str)
print('dec str: ' + dec_str)
Though this code encrypts the data with 192 and 256 bit encryption and successfully decrypt that too but my other .Net and Ruby application only able to decrypt the data which was encrypted using 128 encryption.
Note .Net and Ruby application are successfully tested with each other and with online encryption tool with all encryption types.
Note that my application requires AES-CBC mode and PKCS#7 padding and must be run on Python 3.4.
Made it working by padding of 16 bytes for any encryption types. For that I used AES.block_size which is 16 by default for AES.
import base64
from Crypto.Cipher import AES
class AESCipher:
class InvalidBlockSizeError(Exception):
"""Raised for invalid block sizes"""
pass
def __init__(self, key):
self.key = key
self.iv = bytes(key[0:16], 'utf-8')
print(self.key)
print(key[0:16])
def __pad(self, text):
text_length = len(text)
amount_to_pad = AES.block_size - (text_length % AES.block_size)
if amount_to_pad == 0:
amount_to_pad = AES.block_size
pad = chr(amount_to_pad)
return text + pad * amount_to_pad
def __unpad(self, text):
pad = ord(text[-1])
return text[:-pad]
def encrypt( self, raw ):
raw = self.__pad(raw)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
return base64.b64encode(cipher.encrypt(raw))
def decrypt( self, enc ):
enc = base64.b64decode(enc)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv )
return self.__unpad(cipher.decrypt(enc).decode("utf-8"))
e = AESCipher('1234567812345678', 16)
#e = AESCipher('123456781234567812345678', 24)
#e = AESCipher('12345678123456781234567812345678', 32)
secret_data = "hi"
enc_str = e.encrypt(secret_data)
print('enc_str: ' + enc_str.decode())
dec_str = e.decrypt(enc_str)
print('dec str: ' + dec_str)

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

Custom Python Encryption algorithm

Hey, I have been working on this for a while, and I can remebr my brother stepped me through this very same alogorithm.
Basicly, it just adds the ascii values of both the characters from the key, and the phrase.
I can encrypt it with this:
def encrypt(key, string):
encoded = ''
for i in range(len(string)):
key_c = ord(key[i % len(key)])
string_c = ord(string[i % len(string)])
encoded += chr((key_c + string_c) % 127)
return encoded
But I can't seem to remember what we did as far as decrypting. Its difficult to revers a mod :P
Any ideas?
That's simple, let's see how it works. First of all, the encrypted message is obtained by subtracting the key.
enc = msg + key (mod 127)
How can we obtain the original message? That's easy, subtract the key in both sides
enc - key = msg + key - key (mod 127)
And here we get:
enc - key = msg (mod 127)
For more details, please refer to Modular arithmetic, I think it should belong one of group/field/ring. I'm not an expert in math, for further reading, you should check out Number theory. Here is the refined code:
def encrypt(key, msg):
encryped = []
for i, c in enumerate(msg):
key_c = ord(key[i % len(key)])
msg_c = ord(c)
encryped.append(chr((msg_c + key_c) % 127))
return ''.join(encryped)
def decrypt(key, encryped):
msg = []
for i, c in enumerate(encryped):
key_c = ord(key[i % len(key)])
enc_c = ord(c)
msg.append(chr((enc_c - key_c) % 127))
return ''.join(msg)
if __name__ == '__main__':
key = 'This_is_my_awsome_secret_key'
msg = 'Hello world'
encrypted = encrypt(key, msg)
decrypted = decrypt(key, encrypted)
print 'Message:', repr(msg)
print 'Key:', repr(key)
print 'Encrypted:', repr(encrypted)
print 'Decrypted:', repr(decrypted)
Output
Message: 'Hello world'
Key: 'This_is_my_awsome_secret_key'
Encrypted: '\x1dNV`O\nkO`fD'
Decrypted: 'Hello world'
Decryption is the same, except with minus instead of plus.
But you do not need to inverse the mod, just the + key_c, right? So just add 128, subtract key_c, and do modulo 127 again to keep in range. (instead of the last line, all the other lines are the same as with encrypting.

Categories

Resources