JScript 使用自定义密钥加密和解密字符串

JScript encrypt & decrypt string using custom key

我正在尝试使用带有自定义密钥的 Rijndael 加密然后解密字符串。

Dim obj,arr,i,r,str,enc,utf
dim bytes,bytesd,s,sc,sd
set obj=WScript.CreateObject("System.Security.Cryptography.RijndaelManaged")
Set utf = CreateObject("System.Text.UTF8Encoding")
s="This is a private message"
bytes=utf.GetBytes_4(s)
obj.GenerateKey()
obj.GenerateIV()
set enc=obj.CreateEncryptor()
set dec=obj.CreateDecryptor()

bytec=enc.TransformFinalBlock((bytes),0,lenb(bytes))
sc=utf.GetString((bytec))
msgbox sc

byted=dec.TransformFinalBlock((bytec),0,lenb(bytec))
sd=utf.GetString((byted))
msgbox sd

我重写了这段 vbscirpt 代码,它可以完美地融入 jscript。

但是在我的 jscript 解决方案中,我收到一个错误:“填充无效,无法删除。”解密期间在第 var result = decryptor.TransformFinalBlock(bytes, 0, string.length);.

行抛出错误

我不知道我做错了什么。

function CRYPTO(key) {

    this.Rijndael = WScript.CreateObject("System.Security.Cryptography.RijndaelManaged");
    this.Unicode = WScript.CreateObject("System.Text.UTF8Encoding");

    var MD5 = WScript.CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider");
    MD5.Initialize();

    var bytes = MD5.ComputeHash_2(this.Unicode.GetBytes_4(key));
    this.Rijndael.Key = bytes; this.Rijndael.IV = bytes;

}
CRYPTO.prototype.encrypt = function(string) {

    var bytes = this.Unicode.GetBytes_4(string);
    var encryptor = this.Rijndael.CreateEncryptor();

    var result = encryptor.TransformFinalBlock(bytes, 0, string.length);

    return this.Unicode.GetString(result);

}
CRYPTO.prototype.decrypt = function(string) {

    var bytes = this.Unicode.GetBytes_4(string);
    var decryptor = this.Rijndael.CreateDecryptor();

    var result = decryptor.TransformFinalBlock(bytes, 0, string.length);

    return this.Unicode.GetString(result);

}

var crypto = new CRYPTO(getMotherboardSerialNumber());

var before = "Hello World!";
WScript.Echo(before);

var after = crypto.encrypt(before);
WScript.Echo(after);

var back = crypto.decrypt(after);
WScript.Echo(back);

function getMotherboardSerialNumber() {
    var WMI = GetObject("winmgmts:\\.\root\CIMV2");
    var items = new Enumerator(WMI.ExecQuery("Select * from Win32_BaseBoard"));
    return items.item().SerialNumber;
}

提前致谢,对不起我的英语。

首先,这些代码不同。您的 vbscript enc 方法正确 returns 字节,您将其转换为仅用于显示的字符串。 (这不是特别有用,但不会造成任何伤害。)

您的 jscript encrypt 尝试将随机字节转换为 UTF-8 字符串。大多数时候这会失败。 Rijndael 将返回的绝大多数内容都不是有效的 UTF-8 序列。

摆脱字符串编码,这样更有可能奏效。

注意你的vbscriptasc其实是一个UTF-8编码器,utf是一个ASCII编码器,这很可能是一个错误。此外,您的 jscript 不会创建 IV,并且会不安全地生成其密钥。这两者都显着降低了这种加密的安全性。每次加密都应该有一个随机 IV,就像您在 vbscript 中所做的那样,如果您打算使用序列号之类的东西作为密码,则需要通过 PBKDF2 等 KDF 传递它,而不是单个 MD5哈希。请参阅 Rfc2898DeriveBytes 了解正确的工具。