c# - 如何在 .NET 中复制蓝牙的 CCM 方案?

标签 c# .net ecb

我正在研究一种需要对固件镜像进行端到端加密的固件更新方案。目标设备是蓝牙低功耗芯片,硬件支持蓝牙规范 AES-CCM 中指定的加密技术。我们希望利用此硬件来最大限度地减少代码大小和速度,因此我们需要以构建硬件的格式加密固件镜像。

所以,我正在尝试使用 .NET 的 AesManaged class这样我就可以重现 Bluetooth Spec 中给出的数据样本(p 1547),但我没有得到相同的输出。这是示例数据:

Payload byte length: 08
K: 89678967 89678967 45234523 45234523
Payload counter: 0000bc614e
Zero-length ACL-U Continuation: 0
Direction: 0
Initialization vector: 66778899 aabbccdd
LT_ADDR: 1
Packet Type: 3
LLID: 2
Payload: 68696a6b 6c6d6e6f

B0: 494e61bc 0000ddcc bbaa9988 77660008
B1: 00190200 00000000 00000000 00000000
B2: 68696a6b 6c6d6e6f 00000000 00000000

Y0: 95ddc3d4 2c9a70f1 61a28ee2 c08271ab
Y1: 418635ff 54615443 8aceca41 fe274779
Y2: 08d78b32 9d78ed33 b285fc42 e178d781

T: 08d78b32

CTR0: 014e61bc 0000ddcc bbaa9988 77660000
CTR1: 014e61bc 0000ddcc bbaa9988 77660001

S0: b90f2b23 f63717d3 38e0559d 1e7e785e
S1: d8c7e3e1 02050abb 025d0895 17cbe5fb

MIC: b1d8a011
Encrypted payload: b0ae898a 6e6864d4

现在,我很乐意在没有身份验证的情况下进行加密。我注意到 MIC 和加密有效载荷分别是 T 和有效载荷与 S0 和 S1 的异或,所以我的目标只是生成 S0。我的理解是,我应该能够通过使用 key K 对 CTR0 数组进行 ECB 处理来做到这一点:

//I've tried a few endian-ness permutations of K, none work
byte[] sampleKey = { 0x23, 0x45, 0x23, 0x45, 0x23, 0x45, 0x23, 0x45,
                    0x67, 0x89, 0x67, 0x89, 0x67, 0x89, 0x67, 0x89};
byte[] sampleCtr0 = { 01, 0x4e, 0x61, 0xbc, 00, 00, 0xdd, 0xcc,
                    0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 00, 00 };
byte[] encrypted;

using (AesManaged aesAlg = new AesManaged())
{
    aesAlg.Mode = CipherMode.ECB; //CTR implemented as ECB w/ manually-incrementing counter

    // Create an encrytor to perform the stream transform.
    ICryptoTransform encryptor = aesAlg.CreateEncryptor(sampleKey, zeros); //zeros is a byte array of 16 0's

    // Create the streams used for encryption.
    using (MemoryStream msEncrypt = new MemoryStream())
    {
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        {
            using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
            {
                //Write all data to the stream.
                swEncrypt.Write(sampleCtr0);
            }
            encrypted = msEncrypt.ToArray();
        }
    }
}

我希望在加密 中看到 S0,但我没有。怎么了?

最佳答案

没有方法StreamWriter.Write(byte[])。相反,您正在调用 StreamWriter.Write(object),它会调用对象上的 ToString。这将返回“System.Byte[]”,然后对其进行 UTF8 编码并写入您的 CryptoStream

byte[] sampleCtr0 = { 01, 0x4e, 0x61, 0xbc, 00, 00, 0xdd, 0xcc,
                    0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 00, 00 };
using (var mem = new MemoryStream())
{
    using (var wri = new StreamWriter(mem))
    {
        //Write all data to the stream.
        wri.Write(sampleCtr0);
    }
    Console.WritELine(Encoding.UTF8.GetString(mem.ToArray()));
}

产生:

System.Byte[]

不要使用StreamWriter 将二进制数据写入流。使用 Stream.Write(就像您所做的那样)将数据直接写入流,或者使用 BinaryWriter

StreamWriter 设计用于写入必须通过传递给构造函数的 Encoding 编码为字节的字符。这默认为 Encoding.UTF8

关于c# - 如何在 .NET 中复制蓝牙的 CCM 方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47948639/

相关文章:

python - 在 Python 中实现 AES/ECB/PKCS5 填充

c# - Ninject 使用寄存器类型获取单实例 Controller 错误

asp.net - 如何使用 Rc1 - Final 将 dxn 运行时设置为 .net 4.6.1

c# - 在 WPF 中暂停 Storyboard?

c# - 使用 ninject.extensions.conventions 多次绑定(bind)服务

.net - 从 WPF 应用程序显示 "Select Users and Groups"对话框?

aes - 如何检测分组密码模式

swift - 在 SWIFT 中加密和解密

c# - OnDestroy 在 Unity 中可靠吗?

c# - 将列表中的元音字母转换为大写