(基于Nordic)Android 蓝牙mesh协议栈问题修复之-AppKey解密问题修复

  • 背景
  • 问题分析
  • 修改内容

背景

  • 首先贴上官方github地址https://github.com/NordicSemiconductor/Android-nRF-Mesh-Library
  • 本次修改基于官方SDK 2.4.1版本.
  • 阅读此文章之前,我们默认您对蓝牙mesh协议已经有了一定了解.
  • 本次修复了一个问题,该问题是关于在收到蓝牙数据包的时候寻找appkey去解密数据包的时候发生的一个错误.

问题分析

出现此问题的时候,是一个很偶然的情况下,发现配网不成功,并且,一旦不成功,此设备将永远不成功,报出的异常是数据包解密出现了错误.
经过定位排查,发现是SDK的摘要算法( AID = k4(APP key) )出现了问题,因为不同的appkey通过摘要算法,会解出来相同的aid(appkey id),一旦会解出来相同的aid,那么在我的appkey list里面就会永远只会默认取第一个appkey,如果那个appkey不是我的目标appkey,那么就会就出现解数据包出错的问题.我们来看一下获取appkey的方法:

       @Override
        public byte[] getApplicationKey(final int aid) {
            for (ApplicationKey key : mMeshNetwork.getAppKeys()) {
                final byte[] k = key.getKey();
                if (aid == SecureUtils.calculateK4(k)) {
                    return key.getKey();
                }
            }
            return null;
        }

通过以上代码,我们可以看出此方法会遍历所有的appkeys,然后通过k4算法计算出aid,如果找到目标的aid,那么就认为找到了appkey了.很显然,如果正好两个appkey可以算出同样的aid,那么问题就会发生.

修改内容

那么我们该如何避免此问题呢?

如果想修改k4摘要算法,那么几乎是不可能的,因为蓝牙的数据本身就很短,因此aid也最多只能有6位,所以出现不同appkey算出相同的aid,是避免不了的.因此我们可以换位思考一下,由于appkey是归属于netwrokKey下面的密钥,因此,如果我们能判断此appkey是否属于此数据包对应的networkKey对应下appkey,那么就能大大避免此现象.因此我们只要加入networkKey的判断即可:

        @Override
        public byte[] getApplicationKey(NetworkKey networkKey,final int aid) {
            for (ApplicationKey key : mMeshNetwork.getAppKeys()) {
                final byte[] k = key.getKey();
                if (aid == SecureUtils.calculateK4(k)
                        && key.getBoundNetKeyIndex() == networkKey.keyIndex) {
                    return key.getKey();
                }
            }
            return null;
        }

我们增加了一个参数,引入networkKey,在遍历appkey的时候,再判断这个appkey是否属于此数据包的networkKey下面的密钥即可.

因此,我们几乎可以避免出现appkey解密出来相同的aid的情况.

此外,我们还有另一种思路,就是拿每一个appkey都尝试去解密数据包,直到将数据解密出来,否则就解密失败.

如果任何疑问,请联系邮箱:[email protected]

你可能感兴趣的:(Mesh,android,java)