最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

在 Node.js 中使用 DES 加密,在 VB.net 中解密

网站源码admin28浏览0评论

在 Node.js 中使用 DES 加密,在 VB.net 中解密

在 Node.js 中使用 DES 加密,在 VB.net 中解密

我有一些使用 DES 进行加密的旧版 Visual Basic 代码。现在,一个文件在 Visual Basic 中被加密和解密。作为替换代码的第一步,我想将加密转移到 Node.js,同时暂时避免更改 Visual Basic 解密代码。这归结为在 Node.js 中使用 DES 进行加密,以便可以使用当前的 Visual Basic 实现对其进行解密。

问题是 DES 在 Microsoft 的 DESCryptoServiceProvider 类中的实现非常不透明。我已经能够弄清楚 CBC(密码块链接)用于该模式,填充是 PKCS7,并且没有对密钥应用盐,但缺少细节,例如迭代应用于钥匙。

这是文件当前的加密方式(即我想在 Node.js 中实现的方式):

Sub EncryptFile(ByVal sInputFilename As String, _
               ByVal sOutputFilename As String, _
               ByVal sKey As String)

        Dim fsInput As New FileStream(sInputFilename, _
                                    FileMode.Open, FileAccess.Read)
        Dim fsEncrypted As New FileStream(sOutputFilename, _
                                    FileMode.Create, FileAccess.Write)

        Dim DES As New DESCryptoServiceProvider()

        'Set secret key for DES algorithm.
        'A 64-bit key and an IV are required for this provider.
        DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey)

        'Set the initialization vector.
        DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey)

        'Create the DES encryptor from this instance.
        Dim desencrypt As ICryptoTransform = DES.CreateEncryptor()

        'Create the crypto stream that transforms the file stream by using DES encryption.
        Dim cryptostream As New CryptoStream(fsEncrypted, _
                                            desencrypt, _
                                            CryptoStreamMode.Write)

        'Read the file text to the byte array.
        Dim bytearrayinput(CInt(fsInput.Length - 1)) As Byte

        fsInput.Read(bytearrayinput, 0, bytearrayinput.Length)

        'Write out the DES encrypted file.
        cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length)
        cryptostream.Close()

        fsInput.Close()
End Sub

它基本上对 DESCryptoServiceProvider 的大部分参数和属性使用默认值。

下面是在 Visual Basic 中如何解密生成的文件:

        Dim DES As New DESCryptoServiceProvider()

        'Set the secret key for the DES algorithm.
        DES.Key() = ASCIIEncoding.ASCII.GetBytes("12345678")
        'Set the initialization vector.
        DES.IV = ASCIIEncoding.ASCII.GetBytes("12345678")

        Dim fsread As New FileStream(FileLocation, FileMode.Open, FileAccess.Read)

        Dim desdecrypt As ICryptoTransform = DES.CreateDecryptor()

        Dim cryptostreamDecr As New CryptoStream(fsread, desdecrypt, CryptoStreamMode.Read)

        Dim sr As StreamReader = New StreamReader(cryptostreamDecr)

        'We can now read unencrypted text from sr

问题的症结在于推测了足够多的微软 DES 实现的细节,以用另一种语言重现事物的加密方面。哎呀,如果我可以使用 OpenSSL 对可以由 Visual Basic 中的 DESCryptoServiceProvider 解密的内容进行 DES 加密,我会欣喜若狂。这可以建立在.

这是我在 Node.js 中的想法:

const crypto = require('crypto');
const fs = require('fs');

let key = new Buffer('12345678', 'ascii')
let iv = new Buffer('12345678', 'ascii');

try {
    const data = fs.readFileSync('blah.txt', { encoding: 'binary' });
    console.log(data);

    let cipher = crypto.createCipheriv('des-cbc', key, iv);

    let c = cipher.update(data, 'binary', 'binary');
    
    c += cipher.final('binary');

    fs.writeFileSync('blah.des', c)
}
catch (err) {
    console.error(err);
}

输出与 Visual Basic 加密生成的内容不匹配。尝试使用 Visual Basic 解密(上图)解密 Node.js(上图)加密文件会抛出“要解密的数据长度无效”的错误。

回答如下:

在发布的NodeJS代码中,密文

c
是一个latin1/binary解码字符串,它被写入一个带有
fs.writeFileSync()
的文件,没有在第三个参数中指定编码。这将应用默认编码,即 UTF-8,这会导致密文损坏。正确的是:

fs.writeFileSync('blah.des', c, { encoding: 'binary' })

通过此更改,NodeJS 代码返回与 VB 代码相同的密文。


当前的 NodeJS 代码从文件中读取数据并执行 latin1/binary 解码为字符串。该字符串在加密时采用 latin1/binary 编码,生成的密文经过 latin1/binary 解码。写入文件时执行 latin1/binary 编码(假设已实施上述修复)。

避免编码/解码,以二进制形式处理数据更高效,即从文件中读取数据到缓冲区,加密缓冲区中包含的数据,将密文存储在缓冲区中,然后写入密文从缓冲区到文件:

try {
    const data = fs.readFileSync('blah.txt');
    console.log(data);

    let cipher = crypto.createCipheriv('des-cbc', key, iv);
    let c = Buffer.concat([cipher.update(data), cipher.final()]);

    fs.writeFileSync('blah.des', c)
}
catch (err) {
    console.error(err);
}

此实现也返回与 VB 代码相同的密文。

发布评论

评论列表(0)

  1. 暂无评论