【发布时间】:2017-09-26 17:28:04
【问题描述】:
我正在尝试解密一些由蓝牙模块加密的测试数据。蓝牙的固件是用 C 语言编程的,如果这很重要的话。
加密的数据是:
// Test Bytes - 16 bytes
byte[] testInput = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
// Test key - 16 bytes, 128-bit
byte[] keyBytes = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
// Test nonce - 13 bytes, 104-bit
byte[] nonce = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0a,0x0b,0x0c};
这就是问题所在。使用 AES/CCM 在 C 中加密数据会产生 16 字节的输出,以及 4 字节的 MIC。当我在 Java 中使用 AES/CCM/NoPadding 加密数据时,输出也是 16 字节,但 MAC 为 8 字节。 MAC 和 MIC 这两个术语似乎含糊不清,其中 MIC 用于蓝牙术语。
当我用 Java 加密上面的 testInput 时,我得到与 C 编程加密相同的 16 字节输出。但是,由于 MIC 和 MAC 的长度不同,我无法解密任何一端的数据。
有解决办法吗?
我已经添加了我的 Java 代码:
Cipher cipher = Cipher.getInstance("AES/CCM/NoPadding", "BC");
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(nonce);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal(testInput);
// The first 16 bytes print out equivalently with the C-language AES/CCM
下面是我的输出图像:
下面是 C 输出的图像。
BLE 广告包
编辑:我正在使用选定的答案,但也请查看 Matthew Beckler 的答案。它将提供更深入的答案,并防止以后出现错误。
【问题讨论】:
-
对于蓝牙,MIC 是通过 3 个额外的字节计算的——0x00、0x01 和一个从 PDU 标头的第一个字节计算的字节。没有那个字节,你就无法获得相同的 MIC。
-
@JamesKPolk 你如何建议我来回传递数据?几天来我一直在寻找解决方案。如果您能进一步帮助我,我将不胜感激。
-
首先我要弄清楚MIC是如何产生的/
-
你想加密什么?蓝牙在这里的作用是什么?您想解密通过配对或任意数据加密的 BLE 数据包,并且您碰巧能够重用 BLE 芯片中的 CCM 引擎吗? MIC 不是解密算法的输入,而是当接收方根据随机数、密钥和 AAD 验证接收到的数据时应该匹配的签名。
标签: java android encryption bluetooth aes