c# - 如何使用 javascript slowAES 将加密文本从 C# 发送到 PhantomJS 脚本?

标签 c# javascript aes rijndaelmanaged phantomjs

我有一个在我服务器上的 PhantomJS 中运行的脚本,我需要将密码作为命令行参数传递给该脚本。对于那些不熟悉 PhantomJS 的人来说,它是一个 headless 的 webkit 浏览器,在服务器端运行,没有来自客户端的交互。

为了将密码加载到 PhantomJS 中的虚拟网页对象的上下文中,需要将其存储在包含在特定网页对象中的 javascript 文件中。密码文件只会保留足够长的时间来登录,并将被删除。我有一个故障安全机制,可以在脚本不再需要文件后删除它。我不希望此密码以明文形式存储,因此我想使用 AES 加密。

密码将使用 AES 加密存储在我的数据库中。我知道以这种方式存储密码不是最安全的方法,但脚本需要知道密码,因此散列不是一种选择。

我将在我的 ASP.NET MVC3 Web 应用程序中从 C# 调用此 PhantomJS 脚本,我想使用 AesManaged 或 RijndaelManaged 从 C# 传递加密密码。我对密码学有基本的了解,并设法让一些代码在 C# 和 javascript 中运行。但是,当我从 C# 加密文本时,我无法使用 javascript 对其进行解密。这是我的一些 C# 代码示例:

class Encrypter
{
    public RijndaelManaged rijndael { get; set; }
    public byte[] bytesToDecrypt { get; set; }
    public byte[] bytesToEncrypt { get; set; }

    public Encrypter(string base64key, string base64IV)
    {
        // CBC/128/PKCS7
        rijndael = new RijndaelManaged();
        rijndael.BlockSize = 128;
        rijndael.KeySize = 192;
        rijndael.IV = Convert.FromBase64String(base64IV);
        rijndael.Padding = PaddingMode.PKCS7;
        rijndael.Mode = CipherMode.CBC;
        rijndael.Key = Convert.FromBase64String(base64key);
    }
    public string Encrypt(string strInptData)
    {
        bytesToEncrypt = UTF8Encoding.UTF8.GetBytes(strInptData);

        ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, rijndael.IV);
        bytesToDecrypt = encryptor.TransformFinalBlock(bytesToEncrypt, 0, bytesToEncrypt.Length);

        return Convert.ToBase64String(bytesToDecrypt);
    }

    public string Decrypt()
    {
        ICryptoTransform decryptor = rijndael.CreateDecryptor(rijndael.Key, rijndael.IV);

        byte[] decryptBytes = decryptor.TransformFinalBlock(bytesToDecrypt, 0, bytesToDecrypt.Length);
        // return original string
        return UTF8Encoding.UTF8.GetString(decryptBytes);
    }


    public string ByteArrayToString(byte[] array)
    {
        StringBuilder sb = new StringBuilder();

        sb.Append('[');
        foreach (byte b in array)
        {
            sb.Append(b);
            sb.Append(", ");
        }
        sb.Append("] length : " + array.Length);
        return sb.ToString();
    }
}

javascript 代码使用 slowAES 实现:

$('#encrypt').click(function () {
                var plainText = $('#plaintext').val();
                var $encrypted = $('#encryptedtext');
                var bytesToEncrypt = cryptoHelpers.convertStringToByteArray(plainText);
                var key = cryptoHelpers.base64.decode("bALREf3IwJhzO8JdUwZ55coMydj2YD8R");
                var iv = cryptoHelpers.base64.decode("v/VCTAlV5+kexBFN16WY5A==");

                var result = slowAES.encrypt(bytesToEncrypt, 
                                           slowAES.modeOfOperation.CBC,
                                           key,
                                           slowAES.aes.keySize.SIZE_192,
                                           iv);
                var base64Result = cryptoHelpers.base64.encode(result);
                var hexKey = cryptoHelpers.toHex(key);
                $encrypted.val(base64Result);
                $('div#results').append('<p>bytes to enrypt: ' + bytesToEncrypt + ' length ' + bytesToEncrypt.length + '</p>');
                $('div#results').append('<p>Key: ' + key + '</p>');
                $('div#results').append('<p>IV: ' + iv + '</p>');
                $('div#results').append('<p>Result: ' + result['cipher'] + '</p>');
                $('div#results').append('<p>Hex Key: ' + hexKey + '</p>');
            });
            $('#decrypt').click(function () {
                var $plain = $('#plaintext');
                var encrypted = $('#encryptedtext').val();
                var bytesToDecrypt = cryptoHelpers.base64.decode(encrypted);
                var key = cryptoHelpers.base64.decode("bALREf3IwJhzO8JdUwZ55coMydj2YD8R");
                var iv = cryptoHelpers.base64.decode("v/VCTAlV5+kexBFN16WY5A==");

                var result = slowAES.decrypt(bytesToDecrypt, 
                                           slowAES.modeOfOperation.CBC,
                                           key,
                                           slowAES.aes.keySize.SIZE_192,
                                           iv);
                var plainresult = cryptoHelpers.convertByteArrayToString(result);
                $plain.val(plainresult);
            });

此 javascript 代码只是设置,因此我可以快速测试加密和解密。在 C# 和 javascript 之间进行加密和解密后,我会将密码作为 PhantomJS 的命令行参数进行处理。

key 和 IV 是:

string base64key = "bALREf3IwJhzO8JdUwZ55coMydj2YD8R";
string base64iv = "v/VCTAlV5+kexBFN16WY5A==";

运行文本“test”的加密后, 这是 C# 代码的输出:

BytesToEncrypt: [116, 101, 115, 116, ] length : 4
Base64 Encrypted String: RxNZztdUgbx3KPdvVvMmBg== 
Key: [108, 2, 209, 17, 253, 200, 192, 152, 115, 59, 194, 93, 83, 6, 121, 229, 202, 12, 201, 216, 246, 96, 63, 17 ] length : 24 
IV: [191, 245, 66, 76, 9, 85, 231, 233, 30, 196, 17, 77, 215, 165, 152, 228 ] length : 16 
Result: [71, 19, 89, 206, 215, 84, 129, 188, 119, 40, 247, 111, 86, 243, 38, 6 ] length : 16 
Decrypted: test

这是 javascript 的输出:

Bytes to Encrypt: 116,101,115,116,12,12,12,12,12,12,12,12,12,12,12,12 length 16

Base64 Encrypted String: VRPeZsEJpP7OURwg3FdI8g==

Key: 108,2,209,17,253,200,192,152,115,59,194,93,83,6,121,229,202,12,201,216,246,96,63,17 length 24

IV: 191,245,66,76,9,85,231,233,30,196,17,77,215,165,152,228 length 16

Result: 85,19,222,102,193,9,164,254,206,81,28,32,220,87,72,242 length 16

我已将 PKCS7 填充应用于 C# 代码,因为 slowAES 使用 PKCS7 填充。我什至尝试过使用我自己的 PKCS7 填充实现,但仍然没有得到相同的结果字节数组。如果我遗漏了什么,请告诉我。非常感谢。

最佳答案

不要将密码存储在数据库中!存储盐和散列,并使用盐派生散列。

在此处:Password hashing, salt and storage of hashed values

关于c# - 如何使用 javascript slowAES 将加密文本从 C# 发送到 PhantomJS 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8157560/

相关文章:

c# - 如何通过 HTTP 与 MSMQ 通信?

javascript - 悬停对谷歌字体图标消失的影响

javascript - 如何通过点击按钮使元素为 `display: none`

php - Delphi CryptoBlackBox 和 PHP

security - 如何保护加密 key 免遭逆向工程?

c# - 将字符串从 Delphi 传递到 C# 返回 null。但是,当我从 Delphi 调用 Delphi 库时,它工作正常。如何从Delphi接收字符串

C#转换错误

javascript - Ember 原始 JSON 转换无法正常工作?

certificate - 创建证书 keystore 文件 AES 128

c# - 将 XML 元素读取到 ListView - 我如何将两个变量传递给方法