Home > database >  How to use Node JS to decrypt a file that was encrypted using C#
How to use Node JS to decrypt a file that was encrypted using C#

Time:12-29

I have files encrypted in C# (using DES, PKCS7). I need to decode these files in Node JS.

The code I use to decrypt in C# looks like this:

public string SSFile_Reader( string fileToDecrypt )
{
  DESCryptoServiceProvider provider = new DESCryptoServiceProvider
  {
    Key = Encoding.UTF8.GetBytes( "13^07v90" ),
    IV = Encoding.UTF8.GetBytes( "13^07v90" ),
    Padding = PaddingMode.PKCS7
  };
  
  using( FileStream streamToDecrypt = new FileStream( fileToDecrypt, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ) )
  {
    ICryptoTransform cryptoTransform = provider.CreateDecryptor();
    string outputString = "";

    using( CryptoStream stream2 = new CryptoStream( streamToDecrypt, cryptoTransform, CryptoStreamMode.Read ) )
    {
      try
      {
        using( StreamReader reader = new StreamReader( stream2 ) )
        {
          try
          {
            outputString = reader.ReadToEnd();
          }
          catch
          {
           //handle error here
          }
          stream2.Close();
          streamToDecrypt.Close();

          return outputString;
        }
      }
      catch( Exception exception )
      {
        //handle error here
      }
    }
  }

  return '';
}

I literally need to convert the above to Node JS. I have tried the Node JS code below, but the output is just some random stuff rather than the original encrypted string:

const { Readable } = require("stream");
const { scrypt, scryptSync, randomFill, createCipheriv, createDecipheriv } = require('crypto');
const fs = require('fs');

const [, , pathToEncryptedFile] = process.argv;

if (!pathToEncryptedFile) {
  console.log('No file to decrypt')
  exit()
}

const keyAndIv = '31335e3037763930'; //hex equivalence of 13^07v90
const key = Buffer.from(keyAndIv, 'hex');
const iv = Buffer.from(keyAndIv, 'hex');

const decryptedData = '';

const decipher = createDecipheriv('des', key, iv);

const readableStream = Readable.from(fs.createReadStream(pathToEncryptedFile)
  .pipe(decipher));

readableStream.on("data", (chunk) => {
  decryptedData  = chunk.toString()
})

readableStream.on('end', function () {
  console.log({decryptedData})
});

readableStream.on('error', function (err) {
  console.log({err})
});

I also tried using crypto-js to no avail (https://github.com/brix/crypto-js/issues/396).

This is an example of one of the files I need to decrypt: https://files.fm/u/6pewftkk2

I can also give the C# code that does the encryption if the C# code given above for the decryption does not suffice

CodePudding user response:

One possible variant is to load the ciphertext completely from the file system and decrypt it:

var crypto = require('crypto')
var fs = require('fs')

const algorithm = 'des'; // defaults to 'des-cbc';
const password = 'Password used to generate key';
const key = '13^07v90';
const iv = '13^07v90'; 

const ciphertext = fs.readFileSync('<path to high_classes.ssdata>');
const decipher = crypto.createDecipheriv(algorithm, key, iv);
const plaintext = decipher.update(ciphertext, '', 'utf8')   decipher.final();
console.log(plaintext);

which outputs the following plaintext (for the linked file):

SSS1
SSS2
SSS3

Alternatively, especially for large data, the plaintext can also be streamed to a file. To do this, replace the last block with:

const decipher = crypto.createDecipheriv(algorithm, key, iv);
const readStream = fs.createReadStream('<path to high_classes.ssdata>');
const writeStream = fs.createWriteStream('<path to file where decrypted data should be saved>');
readStream.pipe(decipher).pipe(writeStream);

which creates a file containing the decrypted data.


Note that DES is outdated and insecure these days. Using the key as an IV is also insecure. Typically, a random IV is generated during encryption and passed to the other side along with the ciphertext (usually concatenated).

  • Related