AES Symmetric Encryption with Client-Server Model (Typescript — C#)

abdul salam Chand
6 min readDec 12, 2020

Encryption types can be easily divided into these two categories: symmetric encryption, or single-key encryption, and asymmetric encryption, or public-key encryption.

Symmetric Encryption:

Courtesy:preyproject.com
Courtesy: preyproject.com

In symmetric encryption, there is only one key, and all parties involved use the same key to encrypt and decrypt information.

Perk: symmetric encryption are its faster performance and low resource consumption
Pull: It is inherently older and less secure than its counterpart. It means you’re putting all your trust into a single key you will need to share around a lot.

Takeway: Symmetric encryption is great when working with sensitive data that can be decrypted without risk of exposing its secret key quite often.

Asymmetric Encryption:

Courtesy: preyproject.com

Asymmetric encryption, on the other hand, was created to solve the inherent issue of symmetric encryption: the need of sharing a single encryption key around that is used both for encrypting and decrypting data.

This newer and safer method utilizes two keys for its encryption process, the public key, used for encryption, and the private key used for decryption. These keys are related, connected, and work in the following way:

A public key is available for anyone who needs to encrypt a piece of information. This key doesn’t work for the decryption process. A user needs to have a secondary key, the private key, to decrypt this information. This way, the private key is only held by the actor who decrypts the information, without sacrificing security as you scale security.

Perk: asymmetric is a more advanced encryption standard and secure.
Pull: due to complex standards, the process is slower and resource consuming.

Takeway: Due to this, it is usually utilized in smaller transactions, usually to establish safe communication channels, or authenticating users.

Common Symmetric Encryption Algorithms:

1) AES or Advanced Encryption System: AES is one of the most common symmetric encryption algorithms used today, developed as a replacement to the outdated DES (Data Encryption Standard), cracked by security researchers back in 2005. This new algorithm sought to solve its predecessor’s main weakness, a short encryption key length vulnerable to brute force.

AES is fast, with a variable key length option that gives it extra security. It is ideal when handling large amounts of encrypted data.

2) Blowfish & TwoFish

3) 3DES or Triple Data Encryption Standard: This symmetric algorithm is an advanced form of the deprecated DES algorithm that uses a 56-bit key to encrypt blocks of data. Its concept is simple: it applies DES three times to each block of information, tripling the 56-bit key into a 168-bit one.

Due to applying the same process thrice, 3DES is slower than its more modern counterparts. Furthermore, by using small blocks of data, the risk of decryption by brute force is higher.

Despite its slower speeds and generally outdated status when compared to AES, it is still widely utilized in financial services to encrypt ATM PINs and UNIX passwords.

Common Asymmetric Encryption Algorithms:

1) RSA or Rivest–Shamir–Adleman: RSA uses the factorization of the product of two prime numbers to deliver encryption of 1024-bits and up to 2048-bit key length. This means that it is a slower encryption algorithm. Since it requires two different keys of incredible length, the encryption and decryption process is slow, but the level of security it provides for sensitive information is incomparable.

Since its speed isn’t convenient for processing large amounts of data, RSA encryption is mostly used in digital signatures, email encryption, SSL/TLS certificates, and browsers.

2) ECC or Elliptic Curve Cryptography: ECC uses a fairly more difficult mathematical operation based on elliptic curves on a finite field, in what is called the Elliptic-curve Diffie–Hellman. ECC, or ECDH, a mathematical formula is of such strength that it can match a 1024-bit key system with security with a 164-bit key. In its highest setting, 512-bits, ECC can achieve a comparable level of security of a 15360-bit RSA key!

Considering the aforementioned facts, ECC is considered the future of encryption. It’s asymmetric, yet it is able to provide a security level of 256 bits at a maximum key length of 521 bits, which ensures fast encryption speeds with a high complexity of decryption to ensure sensitive data stays safe.

ECC is also extremely attractive for mobile, where processing power is low and data transfers are high. The low-cost, low-impact, high-security combination makes it the ideal standard for protecting sensitive mobiles and apps.

AES Symmetric Encryption with Client-Server Model:

Key & initialization vector (IV)
A Key in the context of symmetric cryptography is something you keep secret. Anyone who knows your key (or can guess it) can decrypt any data you’ve encrypted with it.

The exact requirements for the IV depend on the chosen chaining mode, but a random 128-bit value is usually fine. It should be different for each message you encrypt. Store it alongside the ciphertext, typically as a prefix.

Cipher Block Chaining Mode:
The Cipher Block Chaining (CBC) mode introduces feedback. Before each plain text block is encrypted, it is combined with the cipher text of the previous block by a bitwise exclusive OR operation. This ensures that even if the plain text contains many identical blocks, they will each encrypt to a different cipher text block. The initialization vector is combined with the first plain text block by a bitwise exclusive OR operation before the block is encrypted. If a single bit of the cipher text block is mangled, the corresponding plain text block will also be mangled. In addition, a bit in the subsequent block, in the same position as the original mangled bit, will be mangled.

Client Side Encryption (Typescript)

import * as CryptoJS from ‘react-native-crypto-js’

// Method to encrypt Using AES
//The key and iv have to be the same on both client and server and should be concealed from any 3rd party if possible. I’ve used a random string “0535627058893800” as both here, but please change it if you use this code.
const key = CryptoJS.enc.Utf8.parse(‘0535627058893800’)
const iv = CryptoJS.enc.Utf8.parse(‘0535627058893800’)
const cipherText = CryptoJS.AES.encrypt(
CryptoJS.enc.Utf8.parse(
JSON.stringify({ username: data.qid, password: data.password })
),
key,
{
iv,
//Make sure the size arguments match the size of your key string, so 128/8 (=16) in this case.
keySize: 128 / 8,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
}
).toString()

Server Side Decryption (C#)

using System;
using System.Configuration;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public static class CryptoHealper
{
readonly static string _cryptoKey;
readonly static string _cryptoIVKey;

static CryptoHealper()
{
_cryptoKey = ConfigurationManager.AppSettings[“CryptoKey”]; //Crypto key is a 16 digit random key.
_cryptoIVKey = ConfigurationManager.AppSettings[“CryptoIVKey”]; //Crypto IV Key is a 16 digit random key. It’s required for CipherMode.CBC algorithm.
}

public static string DecryptStringAES(string encryptedValue)
{
var keybytes = Encoding.UTF8.GetBytes(_cryptoKey);
var iv = Encoding.UTF8.GetBytes(_cryptoIVKey);

//DECRYPT FROM CRIPTOJS
var encrypted = Convert.FromBase64String(encryptedValue);
var decryptedFromJavascript = DecryptStringFromBytes(encrypted, keybytes, iv);

return decryptedFromJavascript;
}

private static string DecryptStringFromBytes(byte[] cipherText, byte[] key, byte[] iv)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
{
throw new ArgumentNullException(“cipherText”);
}
if (key == null || key.Length <= 0)
{
throw new ArgumentNullException(“Key”);
}
if (iv == null || iv.Length <= 0)
{
throw new ArgumentNullException(“IV_key”);
}

// Declare the string used to hold
// the decrypted text.
string plaintext = null;

// Create an RijndaelManaged object
// with the specified key and IV.
using (var rijAlg = new RijndaelManaged())
{
//Settings
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.PKCS7;
rijAlg.FeedbackSize = 128;

rijAlg.Key = key;
rijAlg.IV = iv;

// Create a decrytor to perform the stream transform.
var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

// Create the streams used for decryption.
using (var msDecrypt = new MemoryStream(cipherText))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}

return plaintext;
}
}

Happy coding!!!

https://www.linkedin.com/in/chand-abdul-salam-39786146/

--

--