Skip to content

Implementation

Ricardo Amendoeira edited this page Jan 6, 2017 · 18 revisions

What did we use to implement Group Bank and why?

Web Technologies

Group Bank is a web application developed using the Django Web framework. We chose Django for four reasons: first, easy of development and good documentation; second, its extensive and detailed documentation; third, it is fast; and fourh, security, Django provides some functions that help developers avoid many common security mistakes, such as SQL injection, cross-site scripting, cross-site request forgery and clickjacking. In part we also chose Django because we wanted to develop with Python and Django is the de facto standard Web framework for Python. Python is a very articulated language that allows for easy development and quick deployment.

Note regarding SQL Injection

SQL injection is a type of attack where a malicious user is able to execute arbitrary SQL code on a database. This can result in records being deleted or data leakage. By using Django’s querysets, the resulting SQL will be properly escaped by the underlying database driver providing protection against SQL Injection attacks.

Security Technologies

Our communication protocol is based on two standard technologies: RSA and TLS. RSA is used to authenticate the users and to sign records such as an Invite or an UOMe. TLS is used to encrypt the communication between each component in the system. Since all communication is made using the HTTP protocol, we may refer to the pair as HTTPS.

TLS/HTTPS

HTTPS (basically HTTP with the added security of a TLS connection) aims primarily at providing privacy and data integrity between the client and the web server. When secured by HTTPS, connections between a client and a server have one or more of the following properties:

  • the connection is private and we are protected against replay attacks, because symmetric cryptography is used to encrypt the data transmitted. The keys for this symmetric encryption are generated uniquely for each connection and are based on a shared secret negotiated at the start of the session. The negotiation of a shared secret is both secure (the negotiated secret is unavailable to eavesdroppers and cannot be obtained, even by an attacker who places themselves in the middle of the connection) and reliable (no attacker can modify the communications during the negotiation without being detected).
  • server authentication, the identity of the server can be authenticated using public-key cryptography in conjunction with certificates.
  • the connection ensures integrity because each message transmitted includes a message integrity check using a message authentication code to prevent undetected loss or alteration of the data during transmission.

For all this reasons, HTTPS is the standard secure protocol used in every web application. And we are no exception. It is always a good decision to use standard protocols since it saves us the trouble of reinventing the will and, above all, because those protocols are much well tested and verified than any other protocol that we could come up with.

RSA

RSA is an asymmetric cryptosystem. It uses two different but mathematically linked keys, one public and one private. The public key can be shared with everyone, whereas the private key must be kept secret. In RSA cryptography, both the public and the private keys can encrypt a message; the opposite key from the one used to encrypt a message is used to decrypt it. This attribute is one reason why RSA has become the most widely used asymmetric algorithm: It provides a method of assuring the confidentiality, integrity, authenticity and non-reputability of electronic communications and data storage. Here we use RSA for two different purposes: authentication and non-repudiation.

We rely on digital signatures to authenticate users and to prevent entities from repudiating some of their activity. For actions like invitations, registrations, and transactions signatures of the entities involved are kept to avoid non-repudiation. Consequently, we should guarantee that signing and verifying is done correctly. Although the algorithm used to sign a message and verify the signature is the same as for encrypting and decrypting, there are very important differences between the two processes. First of all, you sign the hash of the message and not the message itself, opposed to encrypting where you encrypt the actual message. Consequently, to verify have to have the message itself and compute its hash value, then decrypt the signature and compare the hash of the message with the result of the decryption. To summarize:

Signing:

  1. you have the message: m
  2. you compute the hash of the message: hash(m)
  3. and sign by encrypting the hash: signature = encrypt(hash(m))

Verifying:

  1. you need to have the actual message: m
  2. you compute the hash of the message: h = hash(m)
  3. you decrypt the signature: s = decrypt(signature)
  4. and then compare the result with the hash of the message: is h == s?

Practical RSA implementations typically embed some form of structured, randomized padding into the value the message m before encrypting/signing it. This padding ensures that m does not fall into the range of insecure plaintexts, and that a given message, once padded, will encrypt to one of a large number of different possible ciphertexts. RSA padding schemes must be carefully designed so as to prevent sophisticated attacks which may be facilitated by a predictable message structure. Once again, the padding scheme used for signing/verifying is different from the one used for encrypting/decrypting. To encrypt/decrypt the current recommended standard is the Optimal Asymmetric Encryption Padding (OAEP) scheme. However, for sign/verify the current recommended standard if the Probabilistic Signature Scheme for RSA (RSA-PSS). Of course, we follow the standards and use the RSA-PSS scheme.

The security of an RSA key is in the size of the modulus. We used a modulus with 2048 bits, which is currently considered to be the minimum size required to ensure safety against brute-force attacks given the current computer power available.

Client application

Initially we intended to follow the current trend and develop a web client that would be able to run in any browser and, consequently, in any operating system (that has a browser). However, we quickly came to the conclusion that using a web application would mean that the user would have to trust the server is sending him the correct code. If you think about it, there is not guarantee that the server will send you a version of the code that you expect. He may send some altered version that does a different thing and may send some sensitive information to the server, for instance you private key.

To solve the problem, we did not see any other solution then developing a native client, and that's what we did. Since all of our work is opensource anybody with the expertise can verify that our code is legit and as long as you download the application from a verified source (such as our github page right here) you can be sure that the code your running does not do any unexpected operations under the hood. The client was developed using python for the backend and the Qt Framework with the PyQt bindings for the frontend.

Besides ensuring that you run a legit version of the application, one of the big advantages of a native client is that immediately protects the user against all attacks related to javascript and browsers in general. Attacks such as Cross site scripting (XSS), Cross site request forgery (CSRF), and Clickjacking that affect millions of web applications (mostly because people are to lazy to protect against them) are not an issue with a native client.