【问题标题】:How to use Node JS to decrypt a file that was encrypted using C#如何使用 Node JS 解密使用 C# 加密的文件
【发布时间】:2022-01-27 03:33:07
【问题描述】:

我有用 C# 加密的文件(使用 DES、PKCS7)。我需要在 Node JS 中解码这些文件。

我在 C# 中用来解密的代码如下所示:

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 '';
}

我确实需要将以上内容转换为 Node JS。我试过下面的 Node JS 代码,但输出只是一些随机的东西,而不是原始的加密字符串:

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})
});

我也尝试使用crypto-js 无济于事 (https://github.com/brix/crypto-js/issues/396)。

这是我需要解密的文件之一的示例:https://files.fm/u/6pewftkk2

如果上面给出的用于解密的 C# 代码不够用,我也可以给出进行加密的 C# 代码

【问题讨论】:

  • ...我尝试过下面的 Node JS 代码:... 还有...发生了什么?
  • ...输出只是一些随机的东西,而不是原始的加密字符串(抱歉信息不完整。问题也更新了)
  • 问题不清楚,encoding is not encryption。您是对文件进行编码还是加密?你能指定你想使用的算法吗?
  • 由于您将明文存储在outputString 中,因此您实际上可以直接加载密文而无需流,例如使用readFileSync() 并使用createDecipheriv() 解密数据。对于从文件系统连续读取的较大密文,以及连续写入文件系统的明文,pipe() 将是一个简单的解决方案。
  • @Thecave3 很抱歉这个错误(我清楚地说如何 *decrypt*... 所以编码是我的错误)。算法是带有 PKCS7 填充的 DES。 This is the gist for the code that I use for the encryption

标签: javascript node.js encryption cryptography cryptojs


【解决方案1】:

一种可能的变体是从文件系统中完全加载密文并解密:

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);

输出以下明文(用于链接文件):

SSS1
SSS2
SSS3

另外,特别是对于大数据,明文也可以流式传输到文件中。为此,请将最后一个块替换为:

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);

创建一个包含解密数据的文件。


请注意,如今 DES 已过时且不安全。使用密钥作为 IV 也是不安全的。通常,在加密过程中会生成一个随机 IV,并与密文(通常是串联的)一起传递给另一方。

【讨论】:

  • 感谢您的努力,@Topaco。当我尝试您在上面发布的代码时,const decipher = crypto.createDecipheriv(algorithm, key, iv) 行出现错误。总结来说,错误是:node:internal/crypto/cipher:116 this[kHandle].initiv(cipher, credential, iv, authTagLength); ^ Error: error:0308010C:digital envelope routines::unsupported
  • 我明白你关于 DES 已经过时的观点。我在 2015/2016 年编写了这段代码。这是一个非常古老的代码库,我实际上是用 Node JS 重写它,我完全删除了这个文件加密功能,因为事后看来,它对我们使用它的服务没有任何帮助。如果有的话,它使客户支持和易于开发成为一种痛苦。感谢您的提醒
  • 我希望我得到的错误与 PKCS7 填充无关?另外,我应该提到我正在使用Node.js v17.0.1
  • 我无法重现此问题。您可以在 repli 上在线运行代码:replit.com/@3hK8cL8H24hwiS7/GrowlingValuablePriorities。由于无法访问文件系统,因此必须从文件2301...71d6(十六进制编码)中导入数据。请在您的环境中运行此代码。如果可行,请使用const ciphertext = fs.readFileSync("&lt;high_classes.ssdata&gt;") 在您的环境中检查导入的密文,并使用console.log(ciphertext.toString('hex')); 将其输出。它应该对应于2301...71d6,并且应该可以解密。
  • 所以我的错误实际上是您正确提到的legacy provider 问题。谢谢你,你救了我的一天!
猜你喜欢
  • 2019-03-04
  • 2013-08-16
  • 1970-01-01
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 2011-06-21
相关资源
最近更新 更多