Send Encrypted Messages

Using Public Key encryption

Via twitter

Public-key, asymmetric security.

You need to setup Twitter OAuth 1.0a and get a;

Consumer key, Consumer secret, access_tok and access_token_sec

https://dev.twitter.com/oauth/application-only

Getting Setup:


In [1]:
# First we need to make a Public, Private key pair. This can be slow
from pktwitter.key_tools import make_key_pair
Bob_key_pair = make_key_pair()
Alice_key_pair = make_key_pair()

Bob and Alice need to add their public key to the end of their twitter description (profile) so that others can send them messages.

Check out https://twitter.com/HeteroT1 as an example.


In [3]:
print('Bob needs this posted to be able to recieve a message:\n{}\n'.format(Bob_key_pair['TwitterKey']))

print('Alice needs to do the same with her public key:\n{}\n'.format(Alice_key_pair['TwitterKey']))

# Bob and Alice might want to save there private keys to a file or store them somewhere safe. 
# The keys as a set of 3 long integers and a bit value
print("Bob's Private key:\n{}\nBob's Public key:\n{}\n"
      .format(Bob_key_pair['PrivateKey'],
              Bob_key_pair['PublicKey']))
print("Alice's Private key:\n{}\nAlice's Public Key:\n{}\n"
      .format(Alice_key_pair['PrivateKey'],
              Alice_key_pair['PublicKey']))


Bob needs this posted to be able to recieve a message:
|TPK|ÞKϨႴțʄƦʛѦƋyΡcѐΉȬႴƝɪʬҜáΧûႴɼ|xүķϔϮӚäɨշΜΥωѱႯöɾǐTʨѬļƈʂӟḃҙ|ÂДĠŞœȯθΠႱӧυƆǷΏԈǎkμՑțʄƅȘլբХ|Ƌ

Alice needs to do the same with her public key:
|TPK|óƄƊՆΥΓԼԶĸȇɱաӛΗųʒƵίħЅՇƒӬyϐÝ|SႼҊժϛѪIϓɠնȒãϡʄŲƱӨՄʔħһȢŪϫσǑ|òӹքʣŇႭӨǧšḂҪҠϘľӖóδҤʢկWAӧҩҧΈ|Ƌ

Bob's Private key:
{'x': 27657403471585871094465890444953810827012742597176855642812145774287513088666, 'iNumBits': 256, 'g': 49783172582608825090439931528536572729963108461317019503724177253465830989761, 'p': 84010602968391467283490718256050533028696511407968274441507764087538112968459}
Bob's Public key:
{'h': 57636149211200410555532965838568251355515863315036559903391467250388920910653, 'iNumBits': 256, 'g': 49783172582608825090439931528536572729963108461317019503724177253465830989761, 'p': 84010602968391467283490718256050533028696511407968274441507764087538112968459}

Alice's Private key:
{'x': 5746331774452459581422677973318830191535263863490374657880190810551702882159, 'iNumBits': 256, 'g': 18976746918589722008581431930382089595467231294839890483156795397223605566318, 'p': 105249255892536519882876173371448909826523232481298546156621893263843050578083}
Alice's Public Key:
{'h': 104854944498188961839340214988778768586179821105551772497923022000838777775510, 'iNumBits': 256, 'g': 18976746918589722008581431930382089595467231294839890483156795397223605566318, 'p': 105249255892536519882876173371448909826523232481298546156621893263843050578083}

Twitter API key

You need a twitter api key. I load a set below you need your own. Here are instructios showing how to. https://themepacific.com/how-to-generate-api-key-consumer-token-access-key-for-twitter-oauth/994/


In [4]:
import configparser
config = configparser.ConfigParser()
config.read('pktwitter/tests/user_data.ini')
consumer_key = config['HeteroT1']['consumer_key']
consumer_sec = config['HeteroT1']['consumer_sec']
access_tok = config['HeteroT1']['access_tok']
access_token_sec = config['HeteroT1']['access_token_sec']

First we need our twitter connection object.


In [7]:
from twython import Twython
bobs_twitter = Twython(consumer_key, consumer_sec, access_tok, access_token_sec)

Sending a message

Get Public Key

If Bob wants to send a message to Alice he only needs Alice's public key. Lets get that. (we are using the twitter account "HeteroT2" as Alice) The key is compressed so we need to convert it to a key that can be used by our elgamal implementation.


In [8]:
from pktwitter.key_tools import get_public_key, assemble_publickey
Alice = 'HeteroT2'
alice_pub_comp = get_public_key(bobs_twitter, Alice)
print("Alice's cmpressed public key is: \n{}".format(alice_pub_comp))
print("You can see this on twitter at: https://twitter.com/heteroT2")

alice_pub = assemble_publickey(alice_pub_comp)
print("\nThe publickey used by elgamal is made using assemble_publickey()")
print("The public key object is alice_pub: {}".format(alice_pub))
print("The public key has the vlaues\np: {}\ng: {}\nh: {}\niNumBits: {}".format(alice_pub.p, alice_pub.g, alice_pub.h, alice_pub.iNumBits))


Alice's cmpressed public key is: 
|TPK|äԵոêӔεӭұιϲϚϳԳӤίƝǔՇϢԹႪՍѹěչž|kʓՒվӛɠaUηĎŚӰՑΫQβԱӭԏİΣʤӎʚοĔ|PĐWɽɣЎтѲҼմǖȒÄɱĠΆůąʇHАўœƝʜǑ|Ƌ
You can see this on twitter at: https://twitter.com/heteroT2

The publickey used by elgamal is made using assemble_publickey()
The public key object is alice_pub: <pktwitter.elgamal2.PublicKey object at 0x1069b3438>
The public key has the vlaues
p: 90875932096819552844785556612588613873835546274321893596879958899737144933243
g: 36482904938826431026020554131207847903542016549871844870165534499814489562137
h: 15133022460434630682730796928323382059448149509228122470007632710200274491318
iNumBits: 256

Encrypting the message

The message gets long when it is encrypted so you can't send 140 characters.


In [9]:
from pktwitter.messaging import encrypt_message
plaintext = "Hello Twitter"
cyphertext = encrypt_message(plaintext, alice_pub)
print("The cypertext is:\n{}".format(cyphertext))


The cypertext is:
µƊկтǡեȂYÜŻüѕԂѮɛեåϛŨӓƿϫɦԇўƜ|GZѣЮЍȘѭCZπэȍȰѯԴҌϝҎәűҨΜΙǎႠұ

Sending a message

You may send as a direct message or as a status update. While the direct message route has the advantage of the recepient knowing the message is for them, and the data contained in the message may only be seen by the recepient, it also allows others to observe the metadata that there is direct interaction between the sender and recepient. With a public status update, there is no metadata with regards to whom the message is for. The recepient has to be expecting the message or just randomly try to decrypt messages.


In [10]:
from pktwitter.messaging import send_direct_messages, send_status_update
from twython import Twython

bobs_twitter = Twython(consumer_key, consumer_sec, access_tok, access_token_sec)

send_direct_messages(bobs_twitter, 'HeteroT2', cyphertext)

send_status_update(bobs_twitter, cyphertext)


message sent 
message sent 
message -  µƊկтǡեȂYÜŻüѕԂѮɛեåϛŨӓƿϫɦԇўƜ|GZѣЮЍȘѭCZπэȍȰѯԴҌϝҎәűҨΜΙǎႠұ

Reading a message

The simplest way to decrypt a messages is to copy the message from twitter. Alica has stored her private key, this could be a ini file of just a text file.


In [13]:
from pktwitter.key_tools import assemble_privatekey
from pktwitter.messaging import decrypt_message

twitter_cyphertext = "µƊկтǡեȂYÜŻüѕԂѮɛեåϛŨӓƿϫɦԇўƜ|GZѣЮЍȘѭCZπэȍȰѯԴҌϝҎәűҨΜΙǎႠұ"

alice_key_file = {'g': 36482904938826431026020554131207847903542016549871844870165534499814489562137,
                  'p': 90875932096819552844785556612588613873835546274321893596879958899737144933243,
                  'x': 7944233631008039187005070093408286827218413351278143022878301217995040934857,
                  'iNumBits': 256}

alice_private = assemble_privatekey((alice_key_file['p'],
                                     alice_key_file['g'],
                                     alice_key_file['x'],
                                     alice_key_file['iNumBits']))

decryptedtext = decrypt_message(alice_private, twitter_cyphertext)
print("The decrypted text is:\n{}".format(decryptedtext))


The decrypted text is:
Hello Twitter