【问题标题】:JScript encrypt & decrypt string using custom keyJScript 使用自定义密钥加密和解密字符串
【发布时间】:2019-12-01 18:49:22
【问题描述】:

我正在尝试使用带有自定义密钥的 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;
}

在此先感谢,对不起我的英语。

【问题讨论】:

  • 为什么需要非标准的 Rijndael Managed?它是在 Rijndael 成为 AES 标准之前实施的,但存在一些差异。
  • 因为它对我有用,我不知道如何使用基类 Rijndael。当我试图找到这样的类时,它失败了var standard = WScript.CreateObject("System.Security.Cryptography.Rijndael");

标签: encryption jscript


【解决方案1】:

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

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

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

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

【讨论】:

  • 有什么方法可以将 Rijndael 序列转换为字符串,例如当我需要将它们写入 utf8 编码文件时?另外我应该如何使用Rfc2898DeriveBytes,我认为这在 jscript/vbscript 中是不可能的。我试图找到像这样var test = WScript.CreateObject("System.Security.Cryptography.Rfc2898DeriveBytes"); 的课程,但没有成功。无论如何,感谢您的提示和时间。
  • 您将需要一个可以采用任意字节集的编码。最流行的是 Base64。十六进制编码也很流行。您可能想探索github.com/as08/ClassicASP.PasswordHashing 我对 vbscript 安全库不够熟悉,无法在那里提供很好的建议;但你想要的是 KDF(PBKDF2,scrypt),而不是简单的加密哈希(MD5,SHA)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2014-06-19
  • 2015-01-25
  • 1970-01-01
相关资源
最近更新 更多