Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this string Base64? How can I tell what is the encoding used?

This is a puzzle to me and I am really annoyed that I cannot solve it! So, if anyone has some free time I would like to here some suggestions on how to solve it!

I use a software that stores the password in an oracle database. The password field is of type Varchar2(100 char). It seems to me that the software encodes the passwords and stores the encoded string in the database.

My password is '1234' and the encoded string is 'cRDtpNCeBiql5KOQsKVyrA0sAiA='. All the passwords in the database are 28 characters long.

The puzzle that I have assigned to myself is to find the encoding and/or encryption of the string. My first check was on Base64

So here is my first test in python (idle):

>>> import base64
>>> encoded = 'cRDtpNCeBiql5KOQsKVyrA0sAiA='
>>> decoded = base64.b64decode(encoded)
>>> decoded
'q\x10\xed\xa4\xd0\x9e\x06*\xa5\xe4\xa3\x90\xb0\xa5r\xac\r,\x02 '
>>> print decoded
qíᄂО*ᆬ䣐ᄚᆬrᆲ

,

Here is my second test:

>>> myString = '1234'
>>> encoded = base64.b64encode(myString)
>>> encoded
'MTIzNA=='
>>> decoded = base64.b64decode('MTIzNA==')
>>> decoded
'1234'

So, my first thought is that this is not Base64 encoded. After I checked wikipedia (https://en.wikipedia.org/wiki/Base64) it seems that Base64 encoded strings are not of fixed size. My second thought is that the string was encrypted and then encoded into Base64 and that is why I get the weird-looking decoded string.

Any ideas?

like image 762
Uphill_ What '1 Avatar asked Nov 30 '10 10:11

Uphill_ What '1


People also ask

How do I know if a string is Base64 encoded?

In base64 encoding, the character set is [A-Z, a-z, 0-9, and + /] . If the rest length is less than 4, the string is padded with '=' characters. ^([A-Za-z0-9+/]{4})* means the string starts with 0 or more base64 groups.

How do you check if a string is encoded or not?

There is no simple method that will tell you whether a given text is encrypted or not as there are many possible encryption algorithms and non-encryption text manipulations.

What encoding is Base64?

Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation. The term Base64 originates from a specific MIME content transfer encoding.

How do you check whether the string is Base64 encoded or not in Python?

All you need to do is decode, then re-encode. If the re-encoded string is equal to the encoded string, then it is base64 encoded. That's it!


2 Answers

It is actually Base64 encoded. However, it is not the password itself that is encoded, but its SHA-1 hash.

from sha import sha
print 'cRDtpNCeBiql5KOQsKVyrA0sAiA='.decode('base64').encode('hex')
print sha('1234').hexdigest()

or for newer versions of Python:

from hashlib import sha1
print 'cRDtpNCeBiql5KOQsKVyrA0sAiA='.decode('base64').encode('hex')
print sha1('1234').hexdigest()

Base64 encodes 3 bytes as 4 characters. As you have 27 characters with one padding, you can see that there are 20 encoded bytes (27*3/4). When something security related is 20 bytes (or 160 bits) long, it's usually a SHA-1. When it's 16 bytes (128 bits), it's usually MD5.

BTW, it's always a good idea to add random salt to the mix so two identical passwords wouldn't stick out in the database. On Linux, the crypt module helps you with that and throws in a few more security measures.

Edit: to answer another comment - it's very easy to get the original from the "encrypted" password. There's a technique that got famous a few years back called Rainbow Tables. There are even online versions of it. Just type in your hash in hex (7110eda4d09e062aa5e4a390b0a572ac0d2c0220) and it'll give you 1234 in a second.

like image 126
kichik Avatar answered Nov 02 '22 06:11

kichik


While len(decoded) = 20 then I guess that this is Base64 encoded SHA1 hash.

You can create such coded passwords by:

import hashlib
import base64
passwd = '1234'
hp = base64.b64encode(hashlib.sha1(passwd).digest())
print hp
print len(hp)

As for such storing passwords: it is not very good while many crackers can use "rainbow" tables with precomputed MD5, SHA1 and other hashes and they can get password based on such hash. To prevent it "salt" should be used: hash(salt+passwd), such salt can be random string saved in database per user or for example user login (something that never can be changed).

like image 34
Michał Niklas Avatar answered Nov 02 '22 06:11

Michał Niklas