Use Advanced Encryption Standard Algorithm (AES) to encrypt text with TypeScript and decrypt it using C# for enhanced security measures

Struggling with implementing encryption in TypeScript and decryption in C#. After searching online, I found some resources related to JavaScript, not TypeScript.

Encrypt in JavaScript and decrypt in C# with AES algorithm

Encrypt text using CryptoJS library in Angular2

How to import non-core npm modules in Angular 2 for encryption?

I followed the above links to implement encryption/decryption in my application.

This is the code written in myservice.ts:

import * as CryptoJS from 'crypto-js';

var key = CryptoJS.enc.Utf8.parse('7061737323313233');
var iv = CryptoJS.enc.Utf8.parse('7061737323313233');
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse("It works"), key,
    {
        keySize: 128 / 8,
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });

var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
    keySize: 128 / 8,
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});

console.log('Encrypted :' + encrypted);
console.log('Key :' + encrypted.key);
console.log('Salt :' + encrypted.salt);
console.log('iv :' + encrypted.iv);
console.log('Decrypted : ' + decrypted);
console.log('utf8 = ' + decrypted.toString(CryptoJS.enc.Utf8));

Before adding this code in myservice.ts, I added the dependency "crypto-js": "^3.1.9-1" in package.json.

Even after successfully restoring the packages, CryptoJS still shows an error in myservice.ts stating cannot find name as CryptoJS.

Could you guide me on how to import CryptoJS from node modules and explain how to encrypt a string in TypeScript and decrypt it in C# using Advanced Security Algorithm (AES)?

Pradeep

Answer №1

I encountered a similar issue when working with Angular 4 and Angular-Cli version 1.0.0. Here's what resolved the issue for me:

npm install crypto-js --save
npm install @types/crypto-js --save

Once you have executed these two commands, make sure to include a reference to the crypto-js library in your angular-cli.json file within the "scripts" array. In my situation, it looked like this:

"scripts": [
    "../node_modules/crypto-js/crypto-js.js"
]

You will find a subdirectory named crypto-js inside the node_modules/@types directory. Point to the node_modules/@types/crypto-js/index.d.ts file in your code using a triple-slash directive. This helps the compiler recognize that the typings file is required to compile the module file:

/// <reference path="relative_path_to_cypto_folder/index.d.ts" />

Alternatively, you can use the "types" attribute instead of "path" since you're referencing a typings definition within node_modules/@types:

/// <reference types="crypto-js" />

After completing these steps, you are ready to utilize your code as usual:

/// <reference types="crypto-js" />

import * as CryptoJS from 'crypto-js';

var key = CryptoJS.enc.Utf8.parse('7061737323313233');
var iv = CryptoJS.enc.Utf8.parse('7061737323313233');
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse("It works"), key,
{
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});

var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});

console.log('Encrypted :' + encrypted);
console.log('Key :' + encrypted.key);
console.log('Salt :' + encrypted.salt);
console.log('iv :' + encrypted.iv);
console.log('Decrypted : ' + decrypted);
console.log('utf8 = ' + decrypted.toString(CryptoJS.enc.Utf8));

Answer №2

npm install crypto-js

//Include these imports in your TypeScript file
import * as CryptoJS from 'crypto-js';

// Define key and initialization vector values
private key = CryptoJS.enc.Utf8.parse('4512631236589784');
private iv = CryptoJS.enc.Utf8.parse('4512631236589784');

// Methods for encryption and decryption using AES
encryptUsingAES256() {
    var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(JSON.stringify("Your JSON Object data or string")), this.key, {
        keySize: 128 / 8,
        iv: this.iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    console.log('Encrypted :' + encrypted);
    this.decryptUsingAES256(encrypted);
    return encrypted;
}

decryptUsingAES256(decString) {
    var decrypted = CryptoJS.AES.decrypt(decString, this.key, {
        keySize: 128 / 8,
        iv: this.iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    console.log('Decrypted : ' + decrypted);
    console.log('utf8 = ' + decrypted.toString(CryptoJS.enc.Utf8));

}

Here is the C# code for encoding or decoding.

public class Encryption {
    public static string DecryptStringAES(string cipherText) {
        var keyBytes = Encoding.UTF8.GetBytes('4512631236589784');
        var iv = Encoding.UTF8.GetBytes('4512631236589784');

        var encrypted = Convert.FromBase64String(cipherText);
        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");
        }

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

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

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

            var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

            try {
                using(var msDecrypt = new MemoryStream(cipherText)) {
                    using(var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) {

                        using(var srDecrypt = new StreamReader(csDecrypt)) {
                            plaintext = srDecrypt.ReadToEnd();
                        }

                    }
                }
            } catch {
                plaintext = "keyError";
            }
        }

        return plaintext;
    }

    public static string EncryptStringAES(string plainText) {
        var keyBytes = Encoding.UTF8.GetBytes('4512631236589784');
        var iv = Encoding.UTF8.GetBytes('4512631236589784');

        var encryptedFromJavascript = EncryptStringToBytes(plainText, keyBytes, iv);
        return Convert.ToBase64String(encryptedFromJavascript);
    }

    private static byte[] EncryptStringToBytes(string plainText, byte[] key, byte[] iv) {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0) {
            throw new ArgumentNullException("plainText");
        }
        if (key == null || key.Length <= 0) {
            throw new ArgumentNullException("key");
        }
        if (iv == null || iv.Length <= 0) {
            throw new ArgumentNullException("iv");
        }
        byte[] encrypted;

        using(var rijAlg = new RijndaelManaged()) {
            rijAlg.Mode = CipherMode.CBC;
            rijAlg.Padding = PaddingMode.PKCS7;
            rijAlg.FeedbackSize = 128;

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

            var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

            using(var msEncrypt = new MemoryStream()) {
                using(var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) {
                    using(var swEncrypt = new StreamWriter(csEncrypt)) {
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }

        return encrypted;
    }
}

Answer №3

const secureData = (data: string):any => { var result=CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(data), secretKey,
    {
        keySize: 128 / 8,
        iv: initializationVector,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });

    return result.toString();
}

const retrieveData = (encrypted: string):any => {
    var result= CryptoJS.AES.decrypt(encrypted, secretKey, {
        keySize: 128 / 8,
        iv: initializationVector,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });

    return result.toString(CryptoJS.enc.Utf8);
}
//----
//Implementation example

var secretKey = CryptoJS.enc.Utf8.parse('7061737323313233');
var initializationVector = CryptoJS.enc.Utf8.parse('7061737323313233');
var encryptedData = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse("Secure this data"), secretKey,
    {
        keySize: 128 / 8,
        iv: initializationVector,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });

var decryptedData = CryptoJS.AES.decrypt(encryptedData, secretKey, {
    keySize: 128 / 8,
    iv: initializationVector,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});
//---Extracting the encrypted and decrypted strings
console.log('Encrypted data:' + encryptedData).toString();;
console.log('Decrypted data:' + encryptedData.toString(CryptoJS.enc.Utf8));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Wrapping text around an image using two distinct Angular components

Can text wrap around an image in Angular even if they are in separate components? Or do the text and image have to be within the same component for this to work, regardless of whether the image is on the left or right side? https://i.stack.imgur.com/hdlxD ...

When an unexpected error occurs, the Angular code will terminate the loop

My code currently stops running when the server quits due to an unhandled exception. I want to make two additions to the code, but I'm unsure where to place them. I need to add error handling for exceptions, capturing the error and displaying it. ...

ESLint has issued a warning indicating that the selector must be utilized as an element

Running Angular 12 and ESLint together has raised some issues for me. Whenever I run ng lint, ESLint reports a problem with the selector below. 10:13 error The selector should be used as an element (https://angular.io/guide/styleguide#style-05-03) @an ...

Issue with Static Injector: GameService cannot be injected with HttpClient in the AppModule

I'm encountering an issue with a library I created in Angular. The library makes API calls using HttpClient, but when I try to access a class from the library called GameService, I receive an error message: "Error Static Injector: StaticInjectorError( ...

Using React with Typescript to display components generated from the `map` function

In my scenario, I have retrieved data from a JSON file and am also utilizing a utility function that selects 5 random entities from an object Array. This particular array contains 30 entities. Struggling with displaying the 5 random jockeys stored in the ...

What's causing the subscription feature to malfunction in a fresh browser tab?

I am facing an issue with camera entries on an angular website. Whenever I click on an entry, a new window opens to display the camera livestream. However, I am having trouble with the subscribe functionality. Important note: Once the window is open, subs ...

Elegantly intersect two types of functions in Typescript

Two function types are defined as follows: wrapPageElement?( args: WrapPageElementBrowserArgs<DataType, PageContext, LocationState>, options: PluginOptions ): React.ReactElement .. and .. wrapPageElement?( args: WrapPageElementNodeArgs<Data ...

I want to search through an array of tuples to find a specific value in the first index, and if there is a match, I need to return the value in the second index of the matching tuple

I am dealing with an array of tuples: var tuparray: [string, number][]; tuparray = [["0x123", 11], ["0x456", 7], ["0x789", 6]]; const addressmatch = tuparray.includes(manualAddress); In my function, I aim to verify if the t ...

Requesting Next Page via Angular GET Method for Paginated API

Having trouble loading data from a paginated REST API using the code below. Any suggestions for a better approach are welcome! component.ts import { Component, OnInit } from '@angular/core'; import {HttpClient} from '@angular/common/http&a ...

Setting a maximum value for a text box input in Angular for enhanced bot functionality

Currently, I am working with Angular 7 and I find myself trying to incorporate the min and max properties into a textbox. However, I seem to be encountering some difficulties in achieving this. <div> <input type='text' [(ngModel)]= ...

Angular 5 combined with Electron to create a dynamic user interface with a generated Table

I am working on an Angular Pipe: import {Pipe, PipeTransform} from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import * as Remarkable from 'remarkable'; import * as toc from 'markdown-toc&a ...

GridView is only displaying one item

I am currently working on integrating data into a GridView from two tables located in different databases. At the moment, I am able to populate the first entry successfully but facing issues with populating entries beyond that. Here is the code snippet: ...

A peculiar app.exe is freezing upon launch

For the past 6 years, I have been developing .NET applications without any issues. However, today I encountered a strange problem. When I copied all my application files (.exe, .dll, configs, etc.) to another machine, I discovered that clicking on the .ex ...

When attempting to post data using jQuery, an object is encountered that does not have a parameterless constructor

Here is the code snippet I am using with jQuery to post data and register a band: var formData = new FormData(); var file = document.getElementById("CoverPicture").files[0]; formData.append("file", file); var Name = $('#Name').val(); var Genre = ...

Node appears to be struggling to find the cors

I added the cors package and confirmed that it's inside the node_modules directory. However, I keep encountering this error message. /usr/src/app/node_modules/ts-node/src/index.ts:859 server | return new TSError(diagnosticText, diagnosticCodes, ...

An issue occurred during the compilation of an Angular6 project

I am embarking on my first Angular project and may not grasp every detail perfectly. In my search for guidance, I came across the command "ng build --prod" on Google and decided to give it a try. Everything seemed to be going smoothly at first until an err ...

Issue with Angular 2: OnInit Lifecycle Hook - The values retrieved from the Service's subscribe function are not being properly assigned to the Component fields

Exploring Angular2 and diligently following their tutorials. The current focus is on creating a Service that retrieves data from a json server: import { Injectable } from '@angular/core'; import { Http, Response } from '@angular/http&apo ...

Storing JSON data retrieved from an API into a class property using the fetch function: a step-by-step guide

I am faced with the challenge of communicating with a localhost API that I have created in my React application class. This API is responsible for returning a list of JSON data, and my goal is to store this data in a property. Having limited knowledge abo ...

What is the best way to integrate Next.js with Strapi (or the other way around)?

My goal is to develop an application utilizing Next.js for the frontend, fetching data from a Strapi API hosted on the same server. The plan is to have Strapi handle API and admin routes, while Next.js manages all other routes. I intend to use fetch in Nex ...