appengine base64 encoded string is different from my local machine's - python

This is the code:
>>> import base64
>>> id = 1
>>> key = "secret key very long"
>>> enc = base64.urlsafe_b64encode(str(id)+key)
>>> enc
'MXNlY3JldCBrZXkgdmVyeSBsb25n'
>>> base64.urlsafe_b64decode(enc)
'1secret key very long'
Works as intended on my machine, but when I upload this code to google appengine, both encoded and decoded strings are totally different. How come?
EDIT 1:
this is the actual code:
import base64
id = 18005
key = "r-$b*8hglm+858&9t043hlm6-&6-3d3vfc4((7yd0dbrakhvi"
enc = base64.urlsafe_b64encode(str(id)+key)
print enc
# local machine: MTgwMDVyLSRiKjhoZ2xtKzg1OCY5dDA0M2hsbTYtJjYtM2QzdmZjNCgoN3lkMGRicmFraHZp
# appengine: PXItJGIqOGhnbG0rODU4Jjl0MDQzaGxtNi0mNi0zZDN2ZmM0KCg3eWQwZGJyYWtodmkxODAwNQ==

I can't explain why per se, but decoding the string you got from appengine shows it prepended an '=' to your key; and appended, rather than prepended, the ID.
>>> key='r-$b*8hglm+858&9t043hlm6-&6-3d3vfc4((7yd0dbrakhvi'
>>> base64.urlsafe_b64decode('PXItJGIqOGhnbG0rODU4Jjl0MDQzaGxtNi0mNi0zZDN2ZmM0KCg3eWQwZGJyYWtodmkxODAwNQ==')
'=r-$b*8hglm+858&9t043hlm6-&6-3d3vfc4((7yd0dbrakhvi18005'
>>> '=' + key + str(18005) == _
True
are you absolutely sure you used the same code on the server?

Related

Reading base64 from a part line in Python

I am currently struggling with something that I feel should be basic, currently I have a program that asks for a user input and saves it as a base64 encoded string,
password = base64.b64encode(values['password'].encode('utf-8'))
where password is inputted in a PySimpleGui window. This works perfectly so that
'password' = "password"
password = b'cGFzc3dvcmQ='
the decode works just fine
password = (base64.b64decode(rig.password)).decode('utf-8')
however the problem comes when I save this value to a file, and try and load it back into memory.
filedir = 'Rigdata.txt'
rigfile = open(filedir, 'w',encoding="utf-8")
for rig in rigs:
rigdata = ["\n\nRig "+str(rig.number)+"\n\tRig Number ;"+str(rig.number)+"\n\tRig ID ;"+str(rig.name)+"\n\tIP Address ;"+str(rig.ip)+"\n\tFTP Username ;"+str(rig.username)+"\n\tFTP Password ;"+str(rig.password)]
rigfile.writelines(rigdata)
rigfile.close()
it is stored in the file in the format
some words; the value being saved
This is then read back into into a class line by line splitting the string in 2 and only keeping everything after the semicolon.
password = str(rigdata.readline().replace("\n","")).split(';')[1]
however when read in it returns the base64 as a string whether I do a split and call it as string or not... this then causes the decode to fail as it is the wrong length.
"b'cGFzc3dvcmQ='"
is there any way of easily rectifying this so I can decode the password?
many thanks!
You need a few encoding steps to go from that string value to the original password.
Reference: https://stackabuse.com/encoding-and-decoding-base64-strings-in-python/#decodingstringswithpython
>>> import base64
>>> a = "b'cGFzc3dvcmQ='"
>>> a.split("'")
['b', 'cGFzc3dvcmQ=', '']
>>> b = a.split("'")[1]
>>> b
'cGFzc3dvcmQ='
>>> b64_bytes = b.encode("ascii")
>>> b64_bytes
b'cGFzc3dvcmQ='
>>> string_bytes = base64.b64decode(b64_bytes)
>>> string_bytes
b'password'
>>> string = string_bytes.decode("ascii")
>>> string
'password'

Wrong CMAC generation from Pycryptodome

As per the Example given in the documentation of PyCryptodome
>>> from Crypto.Hash import CMAC
>>> from Crypto.Cipher import AES
>>> secret = b'Sixteen byte key'
>>> cobj = CMAC.new(secret, ciphermod=AES)
>>> cobj.update(b'Hello')
>>> print cobj.hexdigest()
it generates the AES CMAC but when I try the test vector from RFC4493, I get the wrong CMAC.
for example, the test vectors from RFC4493 are:
K 2b7e1516 28aed2a6 abf71588 09cf4f3c
M 6bc1bee2 2e409f96 e93d7e11 7393172a
AES-CMAC 070a16b4 6b4d4144 f79bdd9d d04a287c
But when I tried the same key and message
>>> from Crypto.Hash import CMAC
>>> from Crypto.Cipher import AES
>>> secret = b'2b7e151628aed2a6abf7158809cf4f3c'
>>> cobj = CMAC.new(secret, ciphermod=AES)
>>> cobj.update(b'6bc1bee2 2e409f96 e93d7e11 7393172a')
>>> print cobj.hexdigest()
I got the following output
a3f10a99bd83f4dee4392d65ed9f76c1
The problem in your code is that your are not treating the message or key 2b7e1516 28aed2a6 abf71588 09cf4f3c as a hex number which it is in this case but you are treating it as bytes where each character is stored in it's ASCII representation rather than being stored as the actual value of hex character so f is stored as binary 0100 0110 rather than as binary 1111. While the RFC deal with input as the numbers encoded as HEX characters, so use this code:
from Crypto.Hash import CMAC
from Crypto.Cipher import AES
secret = "2b7e151628aed2a6abf7158809cf4f3c"
msg = "6bc1bee22e409f96e93d7e117393172a"
cobj = CMAC.new(bytes.fromhex(secret), ciphermod=AES)
cobj.update(bytes.fromhex(msg))
res = cobj.hexdigest()
print(res)
which will print correct result of
070a16b46b4d4144f79bdd9dd04a287c
Hope this solve your problem.

Unable to decrypt text in file python

def DecryptMethod(txt_to_decrypt, key):
#ct = txt_to_decrypt
f = open(txt_to_decrypt,'rb')
ct = f.read()
cipher = AES.new(key, AES.MODE_CBC, iv)
pt = unpad(cipher.decrypt(ct), 16)
#decoded_txt = pt.decode()
print(pt)
return pt
testData = DecryptMethod("test1.enc",decrypted_key)
Within my tes1.enc the encrypted version of the text test1.
However, I am unable to decrypt. Everything was alright until
This part.
pt = unpad(cipher.decrypt(ct), 16)
The above part will constantly show the error:
TypeError: Object type <class 'str'> cannot be passed to C code
I've already checked multiple times, but this part constantly throws out this error.
Thank you in advance.
Plaintexts and ciphertexts (input/output) can only be bytes, bytearray or memoryview. In Python 3, you cannot pass strings. In Python 2, you cannot pass Unicode strings
You can convert the string to bytes like this:
b = bytes(mystring, 'utf-8')
For more information, read these docs

How to handle UTF8 string from Pythons imaplib

Python imaplib sometimes returns strings that looks like this:
=?utf-8?Q?Repertuar_wydarze=C5=84_z_woj._Dolno=C5=9Bl=C4=85skie?=
What is the name for this notation?
How can I decode (or should I say encode?) it to UTF8?
In short:
>>> from email.header import decode_header
>>> msg = decode_header('=?utf-8?Q?Repertuar_wydarze=C5=84_z_woj._Dolno=C5=9Bl=C4=85skie?=')[0][0].decode('utf-8')
>>> msg
'Repertuar wydarze\u0144 z woj. Dolno\u015bl\u0105skie'
My computer doesn't show the polish characters, but they should appear in yours (locales etc.)
Explained:
Use the email.header decoder:
>>> from email.header import decode_header
>>> value = decode_header('=?utf-8?Q?Repertuar_wydarze=C5=84_z_woj._Dolno=C5=9Bl=C4=85skie?=')
>>> value
[(b'Repertuar wydarze\xc5\x84 z woj. Dolno\xc5\x9bl\xc4\x85skie', 'utf-8')]
That will return a list with the decoded header, usually containing one tuple with the decoded message and the encoding detected (sometimes more than one pair).
>>> msg, encoding = decode_header('=?utf-8?Q?Repertuar_wydarze=C5=84_z_woj._Dolno=C5=9Bl=C4=85skie?=')[0]
>>> msg
b'Repertuar wydarze\xc5\x84 z woj. Dolno\xc5\x9bl\xc4\x85skie'
>>> encoding
'utf-8'
And finally, if you want msg as a normal utf-8 string, use the bytes decode method:
>>> msg = msg.decode('utf-8')
>>> msg
'Repertuar wydarze\u0144 z woj. Dolno\u015bl\u0105skie'
You can directly use the bytes decoder instead , here is an example:
result, data = imapSession.uid('search', None, "ALL") #search and return uids
latest_email_uid = data[0].split()[-1] #data[] is a list, using split() to separate them by space and getting the latest one by [-1]
result, data = imapSession.uid('fetch', latest_email_uid, '(BODY.PEEK[])')
raw_email = data[0][1].decode("utf-8") #using utf-8 decoder`

Convert PHP to Python

I need help converting the following PHP to python
$plaintext = "MyPassword";
$utf_text = mb_convert_encoding( $plaintext, 'UTF-16LE' );
$sha1_text = sha1( $utf_text, true );
$base64_text = base64_encode( $sha1_text );
echo $base64_text; //ouput = QEy4TXy9dNgleLq+IEcjsQDYm0A=
Convert the string to UTF16LE
Hash the output of 1. using SHA1
Encode the output of 2. using base64 encoding.
Im trying hashlib.sha1 but its not working. Maybe due to this, maybe encodings. Can anyone help
Your PHP code encodes the password to UTF16, little endian; if your password value is a unicode value, that works just fine in Python:
>>> import hashlib
>>> plaintext = u"MyPassword"
>>> utf_text = plaintext.encode('UTF-16LE')
>>> hashlib.sha1(utf_text).digest().encode('base64')
'QEy4TXy9dNgleLq+IEcjsQDYm0A=\n'
The above session was done in Python 2; in Python 3 the u prefix can be omitted as all string values are Unicode.
Got it, i was using the hashlib.sha1 incorrectly.
import hashlib
password = "MYPASSWORD"
result ='QEy4TXy9dNgleLq+IEcjsQDYm0A='
utftext = password.encode("utf-16LE")
m = hashlib.sha1()
m.update(utftext)
sha1text = m.digest()
output = sha1text.encode('base64','strict')
print "output: %s" % output
print "expect: %s" % result
I don't see why this wouldn't work. This works like a charm and prints out the desired result, QEy4TXy9dNgleLq+IEcjsQDYm0A=
from hashlib import sha1
from base64 import b64encode
print(b64encode(sha1("MyPassword".encode("utf-16le")).digest()))

Categories

Resources