首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解密DESFire ReadData会话

解密DESFire ReadData会话
EN

Stack Overflow用户
提问于 2022-01-14 14:52:41
回答 1查看 88关注 0票数 0

我们正在为DESFire数据的解密而奋斗。我们已经成功地对RndA进行了身份验证,并且可以解密RndA,这与我们创建的RndA相同。

现在,我们尝试从0位置读取一个封闭的文件,读取16字节。

从一些java库中我们可以看出,我们必须使用加密命令作为IV进行解密。是那么回事吗?

这里的例子如下:

代码语言:javascript
复制
SessionKey: 0ba1caf83a26a72170149b7504895f34
ReadCommand: bd00000000100000
Crc32C for Cmd: D9CEE76B
Secret: 6a0d0f0d5c8f054b1e5914a42e49728622774c6272e5c34a69ed302251576aaf

因此,现在我们将ReadCommand与Crc32C连接起来:

代码语言:javascript
复制
bd00000000100000D9CEE76B

然后我们的padd零点达到16位字节

代码语言:javascript
复制
bd00000000100000D9CEE76B00000000

然后用会话密钥和IV 0生成e(cmd + crc +填充),以获得用于解密resposne的下一个iv:

代码语言:javascript
复制
77E24803B5401C61F657607923E5A318

现在我们用会话密钥和IV:=e(cmd + crc32)解密这个秘密,并得到:

代码语言:javascript
复制
D1E9A4726C2A5C3FD5938E714C07524EF1F74BD9000000000000000000000000

有许多零点让我觉得我们离答案不远。所以请有人告诉我们,出什么事了?

我们正在为Crc32C使用这个库,在这里,我们在测试中使用的完整代码:

代码语言:javascript
复制
        [Theory]
    [InlineData("6a0d0f0d5c8f054b1e5914a42e49728622774c6272e5c34a69ed302251576aaf", "0ba1caf83a26a72170149b7504895f34", "bd00000000100000")]
    public void DecryptData_Test(string secretS, string sessionKeyS, string cmdS) 
    {
        var cryptoAlgoFactory = new Func<SymmetricAlgorithm>(() => Aes.Create());
        var keyLength = 16;

        var secret = EncriptionHelper.StringToByte(secretS);
        var sessionKey = EncriptionHelper.StringToByte(sessionKeyS);
        var cmd = EncriptionHelper.StringToByte(cmdS);

        var crytoAlgo = cryptoAlgoFactory();
        crytoAlgo.Mode = CipherMode.CBC;
        crytoAlgo.Padding = PaddingMode.None;

        var encryptor = crytoAlgo.CreateEncryptor(sessionKey, new byte[keyLength]);

        var crc32 = BitConverter.GetBytes(Crc32C.Crc32CAlgorithm.Compute(cmd));

        var padding = 0;
        if ((cmd.Length + crc32.Length) % keyLength != 0)
            padding = keyLength - ((cmd.Length + crc32.Length) % keyLength);

        var result = new byte[cmd.Length + crc32.Length + padding];

        Array.Copy(cmd, result, cmd.Length);
        Array.Copy(crc32, 0, result, cmd.Length, crc32.Length);

        var iv = encryptor.TransformFinalBlock(result, 0, result.Length);

        crytoAlgo = cryptoAlgoFactory();
        crytoAlgo.Mode = CipherMode.CBC;
        crytoAlgo.Padding = PaddingMode.None;

        var decryptor = crytoAlgo.CreateDecryptor(sessionKey, iv);

        var plain = decryptor.TransformFinalBlock(secret, 0, secret.Length);

        Assert.NotNull(plain);
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-19 13:48:02

我们已经发现,我们必须用CMACing加密命令,而不需要使用CRC32C。

因此,以下解决方案:

代码语言:javascript
复制
SessionKey: 0ba1caf83a26a72170149b7504895f34
ReadCommand: bd00000000100000
Secret: 6a0d0f0d5c8f054b1e5914a42e49728622774c6272e5c34a69ed302251576aaf

首先使用CMACing加密cmd以获得用于进一步解密的IV (注意使用SessionKey):

代码语言:javascript
复制
A70BEC41E95A706F11F7DA3D59F2F256

然后用IV cmac(cmd)解密CBC模式下的秘密,得到如下结果:

代码语言:javascript
复制
01000030303030313233343536100300F1F74BD9000000000000000000000000

在CMACing中仍然有一些问题,所以我们使用了一个工作良好的NuGet Packege

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70712444

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档