Python - logging in with encryption

5 posts / 0 new
Last post
Benjamin
Python - logging in with encryption

I am having trouble writing python code to log in with an encrypted password. I pull the encryption key and timestamp, and run the following code to encrypt the password:

key, timestamp = get_encryption_key()
decoded_key = key.decode('base64')
rsa_key = RSA.importKey(decoded_key)
encrypted = rsa_key.encrypt(password + '|' + str(timestamp), 'x')
encrypted_password = encrypted[0]

This works. Now, to log in, I must send a /session POST request. For this I am using the requests library: requests.post(url, data, headers). To log in without encryption, I pass the following as data:

data=json.dumps({
'encryptedPassword': False,
'identifier': username,
'password': password
})

And this works fine. However, switching encryptedPassword to True and passing an encrypted_password instead of password throws "UnicodeDecodeError: 'utf8' codec can't decode byte 0x98 in position 0: invalid start byte". The encrypted password can't be encoded as utf8 by json.dumps. If I remove the json.dumps call and pass requests.post the raw python object, I receive a 400 Client Error: Bad Request. Indeed, in general, it seems that no requests are successful if not first encoded with json.dumps, which seems unsurprising.

How do I encode the encrypted password in order to build a successful request?

Chris
Python - logging in with encryption

Hey Benjamin,

Here is some Python 2.7 code that one of our devs hacked around. It requires sticking in values for identifier, password and m_apiKey, but it should give some pointers as to where to Base64 strings and the like.

Cheers,
Chris

import requests
import base64
import json

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5

# In[]

url = "https://demo-api.ig.com/gateway/deal"
identifier = ""
password = ""
m_apiKey = ""
session = "/session/encryptionKey"
m_url = url + session
headers = { "Content-Type": "application/json; charset=utf-8",
"Accept": "application/json; charset=utf-8",
"X-IG-API-KEY": m_apiKey
}

# In[]
r = requests.get(m_url, headers=headers)
# In[]

m_data = r.json()

decoded = base64.b64decode(m_data['encryptionKey'])
rsakey = RSA.importKey(decoded)
message = password + '|' + str(long(m_data['timeStamp']))
input = base64.b64encode(message)
encryptedPassword = base64.b64encode(PKCS1_v1_5.new(rsakey).encrypt(input))

session = "/session"
m_url = url + session
headers = { "Content-Type": "application/json; charset=utf-8",
"Accept": "application/json; charset=utf-8",
"X-IG-API-KEY": m_apiKey,
"Version": "2"
}

payload = json.dumps({ "identifier": identifier,
"password": encryptedPassword,
"encryptedPassword": True
})

# In[]
r = requests.post(m_url, data=payload, headers=headers)
r.status_code
print r.status_code
print r.text

Benjamin
This works perfectly, thank

This works perfectly, thank you very much. I really appreciate the time you and your dev spent on this.

VincentChan
Crypto module

Hi Chris,

I am using Python 3. May help advise from where I can get Crypto module? pip could not make it for me.

Thanks,
Vincent

kiann00
Hi, for this thread.

Hi, for this thread.

I work with python 3.6; and the code Chris listed does not seem to work.

--------------
KeyError Traceback (most recent call last)
in ()
25 m_data = r.json()
26
---> 27 decoded = base64.b64decode(m_data['encryptionKey'])
28 rsakey = RSA.importKey(decoded)
29 message = password + '|' + str(long(m_data['timeStamp']))

KeyError: 'encryptionKey'

-------------------
I get the python error above.
Would someone be able to advise?

Thanks and kind regards

Log in or register to post comments