B4J Tutorial [B4x] RSA example (asyncstreams)

- Changed to B4x as the subs can be used in B4A, too
- "Send File" added (new Button to send a file to the other client)



This tutorial is based on Erel's Asyncstreams example: https://www.b4x.com/android/forum/threads/b4x-network-asyncstreams-b4xserializator.72149/

RSA basics: https://en.wikipedia.org/wiki/RSA_(cryptosystem)

What is RSA? (seen also as https://)

If you want exchange encrypted data between two persons or apps there's a need to exchange the password. Problem here is that you need a secure way to transmit the password (otherwise someone could know it). So how does one transmit this password in a safe way?

Here comes RSA. It uses 2 keys, a public one to encrcypt the data and a private one to decrypt. Sound weird as usually you use the same pw for en-/ and decryption. Some wise people found a way to encrypt with a public key. The message can then be only decrypted with another (private) key. If you need to know how this works, see the link about RSA. It's all about math.

RSA is used only one time to exchange a very secret password at the start of the communication

It's dangerous to use RSA all the time to en-/decrypt all the data you send/receive because some wise mathematicians have a slight chance to extrapolate the key if they can get "enough"t of traffic samples. So we use it (like your browser) only once to exchange the main password.

Workflow

1. App1 connects to App2 via network (here asyncstreams)
2. App2 sends it's public key
3. App1 sends back it's public key
4. App 2 creates a password (B4xEncryption = AES)
5. App 2 encrypts this password with RSA 2048 bit using App 1's Public RSA Key
6. App 1 decrypts the password with it's own Private RSA Key
7. Now both App's know the AES password and use it from here to en-/decrypt (100 chars long)
8. When one of the apps reconnects, the cycle starts again, so we have some kind of a "session password" which is always new, has a length of 100 chars and can be seen as absolutely safe.

Libs needed

ByteConverter
Encryption (Agram) for RSA
jB4xEncryption (for AES)
jNetwork
jRandomAccessFile
JSON
jStringUtils

plus

#AdditionalJar: bcprov-jdk15on-159

How to run the example

1. You need to run different apps on one machine
2. Copy the folder to a new one
3. Rename the copied folder and the B4J-source code (example: RSA1 and RSA2)
4. Start both apps (One in debug to see what happens, the other one in release mode)
5. On one press "listen" on the other press "connect"
6. Take care to use the same ip and port if you run it on the same pc
7. Debug it to see how the workflow is

As in the Asyncstreams example you can send different kind of data (here: strings and a bitmap). I have removed the serializer to have a map where all data is stored (feel free to use it again).

Additionally you see how to pack data in maps (like the image) via Base64 encoding and of course encryption (via bytes and back). Have fun!
 

Attachments

  • RSAExample.zip
    5.9 KB · Views: 531
Last edited:

zapicoj

Member
Licensed User
Longtime User
Thanks for this tutorial @KMatle

Where can I find the additional libraries [ByteConverter] and [Encryption (Agram) for RSA] ?

I have looked around without any luck.

Also, could you please confirm whether this sample code would work with B4A, B4i and B4J ? and what additional libraries would be needed (if any) ?

I need to make work this proof of concept between Android, iOS and Java and I have been struggling to find libraries that implement the relevant classes to use RSA across all these platforms. Is there any standard way? or can you please help me to solve the questions above?

Thanks
 

DonManfred

Expert
Licensed User
Longtime User
Top