.
																						蓝牙技术及其安全特性 
																					
																					
																						   
																						蓝牙(Bluetooth)[1]技术是由Ericsson、IBM、Intel、Nokia和东芝等公司于1994年联合推出的一项短距离无线通信协议。其最终目标是建立一个全球统一的无线连接标准,以实现不同设备制造商生产的产品在近距离内无需电缆线就可实现相互通信。蓝牙具有使用方便、抗干扰能力强、低功耗、低辐射等诸多优点。它支持异步数据信道和同步语音信道,还可以用一个信道同时传送异步数据和同步语音。2003年3月,IEEE批准了兼容蓝牙1.1版本的WPAN标准"IEEE802.15.1",同时还专门成立了四个工作组专门负责IEEE802.15相关标准的制定和完善动作。
																					
																					
																						   
																						蓝牙的基本拓扑结构是微网(Piconet)。在微网中只有一个主设备(Master),它可以同时和至多7个处于激活状态的从设备(Slave)以及至多255个处于休眠状态的从设建立连接关系。微网之间还可以形成散射网(Scatternet),从而扩大了网络的规模。鉴于蓝牙的以上特性,使得它非常适合用来构建无线AdHoc网络。以满足在会议室、广场、车站等场合进行数据交换的需要。
																					
																					
																						   
																						作为正在迅速发展的短距离无线通信技术,蓝牙的安全问题同样越来越受到人们的关注。蓝牙的安全包含两个层面的内容:一是生态安全,即蓝牙设备的电磁辐射对人体的危害。由于蓝牙设备的输出功率只相当于手机的几分之一,在不能证明手机对人体有害的前提下,可以认为蓝牙的生态安全性是可靠的;二是信息安全。蓝牙的的信息安全是指要保证通信双方所传递的信息不被第三方窃听和篡改,这对于蓝牙AdHoc网络尤其重要。本文只讨论蓝牙的信息安全问题,并给出蓝牙认证算法的VisualC++实现方案。
																					
																					
																						蓝牙认证算法描述[2]
																					
																					
																						    几个重要参数
																					
																					
																						    1. 蓝牙设备地址(BD_ADDR)
																					
																					
																						   
																						每个蓝牙设备都有全球唯一且遵循IEEE802标准的48位地址,其地址空间为232,蓝牙地址由三部分组成:低24位地址(LAP)、高8位地址(UAP)和16位非重要地址(NAP)。蓝牙地址可通过蓝牙设备的查询规则自动获得,也可通过人机接口交互获得。
																					
																					
																						    2. 随机数(RAND)
																					
																					
																						   
																						随机数由蓝牙芯片的随机数发生器生成,为128位长。它在蓝牙的安全功能中扮演着重要作用。
																					
																					
																						    3. PIN码
																					
																					
																						   
																						PIN码是个人识别码,其最长为128位。它可以是蓝牙设备提供的固定值,也可以由用户通过人机接口输入值,其默认值为0。在很多应用中,PIN码为4位十进制数。如果PIN码的长度小于128位,则其余位由蓝牙设备地址自动补充,这样PIN码被增强为PIN',PIN码真实长度为PIN'所占的字节数。
																					
																					
																						    4. 链路密钥
																					
																					
																						   
																						链路密钥分为临时性链路密钥和半永久性链路密钥。临时链路密钥在当前会话结束后就不再用,它由E22算法产生。蓝牙安全通信中的初始密钥和主单元密钥都属于临时链路密钥;半永久性链路密钥在当前会话终止后仍可使用的链路密钥,半永久性链路密钥由E21算法产生。蓝牙安全通信中的单元密钥和组合密钥都属于半永久性密钥。
																					
																					
																						    2.2 链路密钥生成算法E2
																					
																					
																						   
																						如上所述,链路密钥分为临时链路密钥和半永久性链路密钥。临时链路密钥的生成算法E22如图2.1(A)所示。在该算法中,输入参数为:RAND、PIN'和L'。算法描述如下:
																					
																					
																						   
																						E22:{0,1}8×L′×{0,1}128×{1,2,…,16}→{0,1}128
																					
																					
																						    (PIN',RAND,L')|→Ar'(X,Y)
																					
																					
																						    式中,L为用户输入的PIN字节数,L'=min{16,L+6}
																					
																					
																						   
																						X=PIN'[0(modL')]∪PIN'[1(modL')]∪…∪PIN'[15(modL')]
																					
																					
																						    Y=RAND[0…14]∪(RAND[15]⊕L')
																					
																					
																						   
																						Ar:{0,1}128×{0,1}128→{0,1}128;(k×x)|→t
																					
																					
																						 
																						 
																					
																					
																						图2.1 临时链路密钥生成算法(A)和半永久性链路密钥生成算法(B)
																					
																					
																						   
																						半永久性链路密钥的生成算法E21如图2.1(B)所示。输入参数为RAND和BD_ADDR。算法描述如下:
																					
																					
																						    E21:{0,1}128×{0,1}48→{0,1}128
																					
																					
																						    (RAND,BD_ADDR)|→Ar'(X,Y)
																					
																					
																						    其中:X=RAND[0…14]∪(RAND[15]⊕6)
																					
																					
																						   
																						Y=BD_ADDR[0(mod6)]∪BD_ADDR[1(mod6)]∪…∪BD_ADDR[15(mod6)]
																					
																					
																						    2.3 蓝牙认证过程及认证算法
																					
																					
																						   
																						蓝牙的认证是在链路密钥(图2.2中的K,下同)的基础上进行的,它可以是临时链路密钥,也可以是半永久性链路密钥。认证可以单向进行,也可互相认证。认证算法为E1,
																					
																					
																						 
																					
																					
																						图2.2 蓝牙设备通信认证过程
																					
																					
																						   
																						输入参数如图2.2所示。认证时,认证设备A生成随机数RANDA并将其发送给被认证设备B,同时,设备A和B各自单独运算得到结果ACO和SRES(SRES'),设备B将自己的SRES发送给设备A以便与SRES'进行核对,如二者不相等,则认证失败,本链路关闭,过一段时间后才会允许新一轮的认证;如果认证成功,则ACO会被认证双方保留并作为将来生成加密密钥用。若经过了多次认证,则保留最后一次认证的ACO。
																					
																					
																						   
																						蓝牙认证算法E1由Ar构造,其算法流程如图2.3所示。算法描述如下:
																					
																					
																						 
																					
																					
																						图2.3 蓝牙认证算法E1数据流程
																					
																					
																						   
																						E1:{0,1}128×{0,1}128×{0,1}48→{0,1}32×{0,1}96
																					
																					
																						    (K,RAND,BD_ADDR)|→(SRES,ACO)
																					
																					
																						   
																						式中,SRES=Hash(K,RAND,BD_ADDR,6)[0,…,3]
																					
																					
																						   
																						ACO=Hash(K,RAND,BD_ADDR,6)[4,…,15]
																					
																					
																						    Hash是一个哈希函数,定义如下所示:
																					
																					
																						   
																						Hash:{0,1}128×{0,1}128×{0,1}8×L×{6,12}→{0,1}128
																					
																					
																						   
																						(K,I1,I2,L)|→Ar'([K'],[E(I2,L)+16(K,I1⊕16I1)])
																					
																					
																						   
																						式中+16表示128位逐位加,然后模(Mod)256;⊕16表示128位逐位异和(XOR)。
																					
																					
																						    函数E把一个L字节的字X扩展到128位,如下所示:
																					
																					
																						    E:{0,1}8×L×{6,12}→{0,1}8×16
																					
																					
																						   
																						(X[0,…,L-1],L)|→(X[i(modL)]i=0…15)
																					
																					
																						   
																						这样,我们每算一次E1,就要计算Ar两次。第二次计算Ar(实际上是Ar')时,密钥K'的产生与K有关,它们的关系如下所示:
																					
																					
																						   
																						K'[0]=(K[0]+233)mod256,K'[1]=K[1]⊕229,
																					
																					
																						   
																						K'[2]=(K[2]+223)mod256,K'[3]=K[3]⊕193,
																					
																					
																						   
																						K'[4]=(K[4]+179)mod256,K'[5]=K[5]⊕167,
																					
																					
																						   
																						K'[6]=(K[6]+149)mod256,K'[7]=K[7]⊕131,
																					
																					
																						   
																						K'[8]=K[8]⊕233,K'[9]=(K[9]+229)mod256,
																					
																					
																						   
																						K'[10]=K[10]⊕223,K'[11]=(K[11]+193)mod256,
																					
																					
																						   
																						K'[12]=K[12]⊕179,K'[13]=(K[13]+167)mod256,
																					
																					
																						   
																						K'[14]=K[14]⊕149,K'[15]=(K[15]+131)mod256.
																					
																					
																						    认证算法的VC++实现
																					
																					
																						    蓝牙认证算法的VC++实现代码核心步骤如下:
																					
																					
																						    int_8bit*function_E21()
																						//生成半永久性链路密钥,略
																					
																					
																						    int_8bit*function_E22()
																						//生成临时性链路密钥,略
																					
																					
																						    int_8bitroundkey[17][16];
																						//定义轮密钥数组,作为生成轮密钥的输入参数
																					
																					
																						    //以下函数生成轮密钥K:
																					
																					
																						    void roundkeygenerate(int_8bit
																						inputkey[16],int_8bit roundkey[17][16])
																					
																					
																						    { ……
																					
																					
																						    for(i=0;i<16;i++)
																					
																					
																						    {
																					
																					
																						    shift(tmp_key);
																						//定义转移函数,对密钥每个字节循环左移3位;
																					
																					
																						    for(int j=0;j<16;j++)
																					
																					
																						    {
																					
																					
																						   
																						roundkey[i+1][j]=tmp_key[(j+i+1)%17]+B[i+1][15-j]%256
																						;
																					
																					
																						    }
																					
																					
																						    }
																					
																					
																						    }
																					
																					
																						    //以下函数实现轮加密:
																					
																					
																						    void roundencrypt(int_8bit
																						k,int_8bit* rand,int_8bit roundkey[17][16])
																					
																					
																						    {……
																					
																					
																						    for(m=0;m<16;m++)
																					
																					
																						    {
																					
																					
																						    switch(m)
																					
																					
																						    {case0:……;
																					
																					
																						   
																						case15:*(rand+m)=(*(rand+m)+roundkey[2*k+1][m]);break;
																					
																					
																						   
																						default:*(rand+m)^=roundkey[2*k+1][m];break;
																					
																					
																						    }
																					
																					
																						    }
																					
																					
																						    }
																					
																					
																						    //以下函数实现Ar: 
																					
																					
																						    void
																						function_Ar(int_8bit*rand,int_8bit
																						roundkey[17][16])
																					
																					
																						    {
																					
																					
																						    for(int_8bit k=0;k<8;k++)
																					
																					
																						    {
																					
																					
																						    roundencrypt(k,rand,roundkey);
																					
																					
																						    ……;
																					
																					
																						    }
																					
																					
																						    for(int_8bit m=0;m<16;m++)
																					
																					
																						    {
																					
																					
																						    switch(m)
																					
																					
																						    {case0:…;
																					
																					
																						   
																						case15:*(rand+m)=*(rand+m)^roundkey[16][m];break;
																					
																					
																						   
																						default:*(rand+m)=(*(rand+m)+roundkey[16][m])%256;break;
																					
																					
																						    }
																					
																					
																						    }
																					
																					
																						    }
																					
																					
																						    //以下函数实现Ar': 
																					
																					
																						    void
																						function_Ar'(int_8bit*rand,int_8bit
																						roundkey[17][16])
																					
																					
																						    {
																					
																					
																						    int_8bit RAND[16];
																					
																					
																						    for(int_8bit i=0;i<16;i++)
																					
																					
																						    RAND[i]=rand[i];
																					
																					
																						    for(int_8bit k=0;k<8;k++)
																					
																					
																						    {
																					
																					
																						    ……
																					
																					
																						    roundencrypt(k,rand,roundkey);
																					
																					
																						    }
																					
																					
																						    for( int_8bit m=0;m<16;m++)
																					
																					
																						    {
																					
																					
																						    switch(m)
																					
																					
																						    {case 0: ……
																					
																					
																						   
																						case15:*(rand+m)=*(rand+m)^roundkey[16][m];break;
																					
																					
																						   
																						default:*(rand+m)=(*(rand+m)+roundkey[16][m])%256;break;
																					
																					
																						    }
																					
																					
																						    }
																					
																					
																						    }
																					
																					
																						    //实现认证算法E1: 
																					
																					
																						    void function_E1(int_8bit
																						address[6],int_8bit RAND[16],int_8bit K[16])
																					
																					
																						    {
																					
																					
																						    int_8bit address128[16];
																					
																					
																						    for(int_8bit
																						m=0;m<16;m++)address128[m]=address[m%6];
																						//地址扩展
																					
																					
																						   
																						K'[0]=(K[0]+233)%256;…;K'[15]=(K[15]+131)%256;K'[1]=K[1]^229;
																						//生成K'
																					
																					
																						    roundkeygenerate(K,roundkey);
																					
																					
																						    function_Ar(rand,roundkey);
																					
																					
																						    for(m=0;m<16;m++)
																					
																					
																						    {
																					
																					
																						    rand[m]=rand[m]^RAND[m];
																					
																					
																						    rand[m]=(rand[m] +
																						address128[m]) % 256;
																					
																					
																						    }
																					
																					
																						    roundkeygenerate(K1,roundkey1);
																					
																					
																						    function_ Ar' (rand,
																						roundkey1);
																					
																					
																						    for(m=0;m<16;m++) RAND
																						[m]=rand[m];
																					
																					
																						    }
																					
																					
																						    void main()
																						//主函数:略
																					
																					
																						    程序运行结果如图 3.1 所示。
																					
																					
																						蓝牙的认证算法通常是由硬件来实现的,以充分利用硬件在运算速度上的优势。但由于在芯片级集成蓝牙的认证功能增加了蓝牙芯片的设计复杂度、体积和商业成本,因而如能将蓝牙的认证功能采用软件的方式实现,无疑将有助于蓝牙技术的推广应用。本文在分析了蓝牙认证算法的基础上,给出了用VC++语言实现该算法的方法。由于采用软件实现的蓝牙认证算法具有良好的可移植性,因而对今后蓝牙的应用研究和开发具有重要的实践意义。
																					
																					
																						 
																					
																					
																						图3.1认证算法E1运行结果