Encryption ZigBee绿色电源AES-CCM

Encryption ZigBee绿色电源AES-CCM,encryption,aes,zigbee,Encryption,Aes,Zigbee,我目前正在研究一个非常简单的ZigBee绿色电源(GP)终端设备实现。目前,我的问题是如何生成正确的MIC(消息标识码)。 我已经有了一个AES-CCM实现,并使用ZigBee Pro规范中的ZigBee绿色电源测试向量对其进行了测试。问题是我得到的结果不正确(与规范中的结果不同) 我还尝试用规范中的其他测试向量(非GP向量)验证我的实现,结果是正确的。所以,我的算法似乎是正确的 GP话筒代码的计算是否与普通ZigBee话筒有所不同??也许有人有另一个为ZigBee GP工作的实现 其他信息:

我目前正在研究一个非常简单的ZigBee绿色电源(GP)终端设备实现。目前,我的问题是如何生成正确的MIC(消息标识码)。
我已经有了一个AES-CCM实现,并使用ZigBee Pro规范中的ZigBee绿色电源测试向量对其进行了测试。问题是我得到的结果不正确(与规范中的结果不同)
我还尝试用规范中的其他测试向量(非GP向量)验证我的实现,结果是正确的。所以,我的算法似乎是正确的

GP话筒代码的计算是否与普通ZigBee话筒有所不同??也许有人有另一个为ZigBee GP工作的实现

其他信息:

我使用的ZigBee规范可在以下位置获得:

上述文件附件C.3中列出了正在工作的测试向量

绿色电源版本的试验矢量见附录H.2。为完整起见,参数如下(附录H.2.3):

规范规定,nonce的构造如下所示:

Nonce: SRC ID || SRC ID || Frame Counter || 0x05
Nonce: 0x21 0x43 0x65 0x87 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00 0x05
计算时需要一个“a”值:

a = Header || Payload
Header = NWK FC || NWK Ext FC || SRC ID || Frame Counter
Header = 0x8C 0x10 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00
Payload = GPD Command ID = 0x20
a = 0x8C 0x10 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00 0x20
最后,对于AES-CBC算法的计算,需要以下参数:

length(a) = 0x0B
L(a) = 0x00 0x0B (big endian encoding of length(a))
AddAuthData = L(a) || a || padding
AddAuthData = 0x00 0x0B 0x8C 0x10 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00 0x20 0x00 0x00 0x00
Flags = 0x49
B0 = Flags || Nonce || padding
B0 = 0x49 0x21 0x43 0x65 0x87 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00 0x05 0x00 0x00
为了生成MIC代码,该算法与加密密钥和B0。。。Bi块(每个16字节)。B0是使用nonce创建的(见上文)。通常AddAuthData和消息块是连接在一起的。但就我所知,绿色电源版本没有可用的消息块。因此,B1。。。Bn仅使用AddAuthData创建我就在这里吗??

B1 = AddAuthData
B1 = 0x00 0x0B 0x8C 0x10 0x21 0x43 0x65 0x87 0x02 0x00 0x00 0x00 0x20 0x00 0x00 0x00
AES-CBC算法E用于每个Bi块。BI是与先前生成的席结果的异或。初始向量X0是长度为16字节的全零位块。 Xi i+1=E(key,席XOR Bi),i=0…N

AES计算的结果是一个16字节的值。但只使用最左边的4个字节。预期结果是:

U = 0xCF 0x78 0x7E 0x72
但我得到:

X2 = 02 1C 9F 9C 40 3A 27 B4 9A 31 64 EA 17 CF 69 D3
U = 0x02 0x1C 0x9F 0x9C

AES-CCM*是AES-CBC(认证)和AES-CTR(加密)的组合

身份验证转换在16B
Bi
缓冲区上运行AES-CBC
B0
是基于
Nonce
构建的,
B1、B2、…、Bn
是解析
AuthData
的结果,其定义为:

AuthData = AddAuthData || PlaintextData
由于您没有有效负载,因此在您的情况下,
PlaintextData
为空,然后
AuthData=AddAuthData

请注意,您的
B0
定义不正确。在Nonce之后没有填充,而是长度
m
(即有效负载长度)。由于没有有效负载(
l(m)=0
),因此结果与此处的填充相同。但是
B0
的正确定义是:

B0 = Flags || Nonce || l(m)
下面是
Bi
缓冲区(不带
0x
前缀的十六进制格式):

使用正确的128b键,AES-CBC步骤产生以下结果:

X0 = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
B0 = 49 21 43 65 87 21 43 65 87 02 00 00 00 05 00 00

X1 = 14 5B B8 1F DE D7 99 45 9D 9B 77 51 B7 31 A3 C1
B1 = 00 0B 8C 10 21 43 65 87 02 00 00 00 20 00 00 00

X2 = 02 1C 9F 9C 40 3A 27 B4 9A 31 64 EA 17 CF 69 D3
总而言之,到目前为止,你的观点是正确的,但你还没有完全正确!您得到的不是
U
,而是
T
身份验证标签(未加密):
T=021c 9F 9C
。要获得
U
,您应该运行加密转换(即使您没有要加密的有效负载)

加密转换使用AES-CTR。计数器称为
Ai
,定义如下:

Ai = Flags || Nonce || Counter
标志
与用于
B0
计算的标志几乎相同,只是保留了3个最低有效位。然后
Flags=0x01
Ai
是:

A0 = 01 21 43 65 87 21 43 65 87 02 00 00 00 05 00 00
A1 = 01 21 43 65 87 21 43 65 87 02 00 00 00 05 00 01
A2 = 01 21 43 65 87 21 43 65 87 02 00 00 00 05 00 02
...
A1、A2、…、An
用于加密您不感兴趣的有效负载。但是
A0
用于生成
U
加密标记。操作基本上是
U=E(键,A0)xor T

       A0 = 01 21 43 65 87 21 43 65 87 02 00 00 00 05 00 00
E(Key,A0) = CD 64 E1 EE 37 25 CF 25 AD 84 00 F0 5C B4 9B 03
        T = 02 1C 9F 9C
        U = CF 78 7E 72

这里是预期结果
U=0xCF 0x78 0x7E 0x72

这里是一个详细的AES-128-CCM*加密Python源代码:

检查规范,看看它对进入MIC计算的“附加数据”有何说明。这是未加密的数据,通常在数据包头中。没有代码,没有示例输入和输出,没有到规范的链接,这是一个离题的问题。很抱歉没有提供所有信息。我编辑了我的问题并添加了用于计算麦克风的数据。我实施的步骤正确吗?还是有什么遗漏??谢谢你帮助我!谢谢你的解释,测试向量对我有用。你知道调试是如何进行的吗?我有一个能量收集开关,带有调试电报(括号中的假定钥匙)3d 01 08 82 ff ff ff ff ff 0c 9e 7d 71 01 e0 02 c5 f2[b8 48 c1 c3 1d e8 9b ae 5d 67 27 53 64 52 a0 ac]ca 30 c0 1a 82 00 00 00 04 11 11 12 13 14 15 16 17 22 60 62 63 64 66 68和消息18 01 08 83 ff ff ff ff ff ff ff ff[8c 30 9e 7d 71 01 83 00 00 10][22 f6 20 37]你在哪里不像预期的那样。你有什么想法吗?
A0 = 01 21 43 65 87 21 43 65 87 02 00 00 00 05 00 00
A1 = 01 21 43 65 87 21 43 65 87 02 00 00 00 05 00 01
A2 = 01 21 43 65 87 21 43 65 87 02 00 00 00 05 00 02
...
       A0 = 01 21 43 65 87 21 43 65 87 02 00 00 00 05 00 00
E(Key,A0) = CD 64 E1 EE 37 25 CF 25 AD 84 00 F0 5C B4 9B 03
        T = 02 1C 9F 9C
        U = CF 78 7E 72