在 C# 中使用 AES-CBC 将编码的 Base64 解密为令牌以提取声明

问题描述 投票:0回答:1

我目前正在处理来自外部第三方的身份验证,该第三方向我们发送编码的 Base64 字符串,我们依次对其进行解码,然后解密它以获取用户声明。这是我用 C# 创建的方法来解密我们从他们那里收到的值:

var key = Encoding.UTF8.GetBytes(_secretKey);
byte[] iv;

using (var aesAlg = Aes.Create())
{
    var decodedBytes = Convert.FromBase64String(_jwtEncryptedToken);

    iv = new byte[16];
    Array.Copy(decodedBytes, 0, iv, 0, iv.Length);

    aesAlg.Key = key;
    aesAlg.IV = iv;
    aesAlg.Mode = CipherMode.CBC;
    aesAlg.Padding = PaddingMode.PKCS7;

    ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);


    using (var msDecrypt = new MemoryStream(decodedBytes))
    {
        using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
        {
            using (var srDecrypt = new StreamReader(csDecrypt))
            {
                return srDecrypt.ReadToEnd();
            }
        }
    }
}

当我尝试将其与收到的编码的 Base64 一起测试时,它总是返回一个错误,指出“输入数据不是完整的块”

附注密钥是 16 个字符,_jwtEncryptedToken 是我收到的编码的 base64

有人可以帮忙吗?

提前致谢。

c# encryption aes cbc-mode
1个回答
0
投票

为了解密,您需要密钥和初始化向量 IV。

不清楚要解密的消息是在 IV 之后还是在另一个变量中。

考虑到您以分开的方式收到 IV 和 Message

string decryptAES(string EncodedToken, string EncryptedMSG)
{
    byte[] key = Encoding.UTF8.GetBytes(_secretKey); 
    byte[] iv;

    using (var aesAlg = Aes.Create())
    {
        var decoded_IV_Bytes = Convert.FromBase64String(EncodedToken);
        var toDecodeBytes = Convert.FromBase64String(EncryptedMSG);

        iv = new byte[16];
        Array.Copy(decoded_IV_Bytes, 0, iv, 0, iv.Length);

        aesAlg.Key = key;
        aesAlg.IV = iv;
        aesAlg.Mode = CipherMode.CBC;
        aesAlg.Padding = PaddingMode.PKCS7;

        ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

        using (var msDecrypt = new MemoryStream(toDecodeBytes))
        {
            using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                using (var srDecrypt = new StreamReader(csDecrypt))
                {
                    return srDecrypt.ReadToEnd();
                }
            }
        }
    }
}

注意IV是用base64编码的,但没有加密。

尝试使用以下代码:

string _secretKey = "1234567890abcdef";
decryptAES("ZmVkY2JhMDk4NzY1NDMyMQ==", "a4/W0T6oxPGbqsHbx3N1gA==");

考虑到您收到了 IV 和消息串联

public static string decryptAES2(string EncryptedMSG)
{
    byte[] key = Encoding.UTF8.GetBytes(_secretKey);
    byte[] iv;
    byte[] toDecodeBytes;

    using (var aesAlg = Aes.Create())
    {
        var decodedBytes = Convert.FromBase64String(EncryptedMSG);
        iv = new byte[16];
        Array.Copy(decodedBytes, 0, iv, 0, iv.Length);

        toDecodeBytes = new byte[decodedBytes.Length - 16];
        Array.Copy(decodedBytes, 16, toDecodeBytes, 0, decodedBytes.Length - 16);

        aesAlg.Key = key;
        aesAlg.IV = iv;
        aesAlg.Mode = CipherMode.CBC;
        aesAlg.Padding = PaddingMode.PKCS7;

        ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

        using (var msDecrypt = new MemoryStream(toDecodeBytes))
        {
            using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                using (var srDecrypt = new StreamReader(csDecrypt))
                {
                    return srDecrypt.ReadToEnd();
                }
            }
        }
    }
}

尝试使用以下代码:

string _secretKey = "1234567890abcdef";
decryptAES2("ZmVkY2JhMDk4NzY1NDMyMWuP1tE+qMTxm6rB28dzdYA=");
© www.soinside.com 2019 - 2024. All rights reserved.