【问题标题】:Different encryption results using C# and CryptoJS使用 C# 和 CryptoJS 的不同加密结果
【发布时间】:2017-09-08 01:48:22
【问题描述】:

我在一个用 C# 编写的服务器应用程序中使用 AES 加密了一些数据。例如,我使用预定义的密钥(32 字节)和 IV(16 字节)...

Key: 81fe1681..6a451c1c
IV:  e83c..ae76

这是我用来加密数据的 C# 代码:

async Task<byte[]> Encrypt(string privateKey, string pin, byte[] data)
{
    using (var sha = SHA256.Create())
    {
        byte[] keyHash = sha.ComputeHash(Encoding.UTF8.GetBytes($"{privateKey}"));
        byte[] pinHash = sha.ComputeHash(Encoding.UTF8.GetBytes($"{pin}"));
        using (Aes aes = Aes.Create())
        {
            byte[] key = keyHash.Slice(0, aes.Key.Length);
            byte[] iv = pinHash.Slice(0, aes.IV.Length);
            using (ICryptoTransform transform = aes.CreateEncryptor(key, iv))
            using (var stream = new MemoryStream())
            using (var cryptStream = new CryptoStream(stream, transform, CryptoStreamMode.Write))
            {
                await cryptStream.WriteAsync(data, 0, data.Length);
                await cryptStream.FlushAsync();

                return stream.ToArray();
            }
        }
    }
}

加密的结果数据看起来像...

534c..28f5

现在,我想使用 CryptoJS 解密客户端应用程序中的数据。我使用完全相同的密钥和IV信息,但解密似乎失败了……至少解密的结果总是空的。

所以,我在客户端加密了数据(当然密钥和 IV 相同),结果密文不同;更准确地说,它是相同的,但最后有更多数据......

534c..28f5bbd5..ac0e

如果我对服务器上的数据进行加密,我最后得不到的额外数据是什么?

如果我解密已在客户端加密的密文,则解密工作。顺便提一下,模式和填充在服务器和客户端都是默认的,即CBCPkcs7;密钥大小应为256。这是我用来解密服务器加密数据的代码:

let keyHash: WordArray = CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(privateKey));
let key: WordArray = CryptoJS.lib.WordArray.create(keyHash.words.slice(0, 8), 32);

let pinHash: WordArray = CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(pin));
let iv: WordArray = CryptoJS.lib.WordArray.create(pinHash.words.slice(0, 4), 16);

let cfg: CryptoJS.lib.IBlockCipherCfg = { iv: iv };
let paramsData: CryptoJS.lib.CipherParamsData = { 
    ciphertext: cipherBuffer
};

let decrypted: WordArray = CryptoJS.AES.decrypt(paramsData, key, cfg);

【问题讨论】:

    标签: javascript c# cryptography aes cryptojs


    【解决方案1】:

    对于写入,块的刷新存在问题。 FlushFinalBlock() 不同于Flush()(或FlushAsync())。你必须两者都做,或者干脆处置CryptoStream。这将解决代码没有写入最后一个数据块的事实。

    async static Task<byte[]> Encrypt(string privateKey, string pin, byte[] data)
    {
        using (var sha = SHA256.Create())
        {
            byte[] keyHash = sha.ComputeHash(Encoding.UTF8.GetBytes($"{privateKey}"));
            byte[] pinHash = sha.ComputeHash(Encoding.UTF8.GetBytes($"{pin}"));
            using (Aes aes = Aes.Create())
            {
                byte[] key = keyHash.Slice(0, aes.Key.Length);
                byte[] iv = pinHash.Slice(0, aes.IV.Length);
    
                Trace.WriteLine($"Key length: { key.Length }, iv length: { iv.Length }, block mode: { aes.Mode }, padding: { aes.Padding }");
    
                using (var stream = new MemoryStream())
                using (ICryptoTransform transform = aes.CreateEncryptor(key, iv))
                {
                    using (var cryptStream = new CryptoStream(stream, transform, CryptoStreamMode.Write))
                    {
                        await cryptStream.WriteAsync(data, 0, data.Length);
                    }
    
                    return stream.ToArray();
                }
            }
        }
    }
    

    打字稿代码似乎可以解密。

    工作小提琴:https://jsfiddle.net/uj58twrr/3/

    【讨论】:

    • 谢谢。这解决了问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    相关资源
    最近更新 更多