public void fetch_status(){ TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);// String str = ""; str += "DeviceId(IMEI) = " + tm.getDeviceId() + "\n"; str += "DeviceSoftwareVersion = " + tm.getDeviceSoftwareVersion() + "\n"; str += "Line1Number = " + tm.getLine1Number() + "\n"; str += "NetworkCountryIso = " + tm.getNetworkCountryIso() + "\n"; str += "NetworkOperator = " + tm.getNetworkOperator() + "\n"; str += "NetworkOperatorName = " + tm.getNetworkOperatorName() + "\n"; str += "NetworkType = " + tm.getNetworkType() + "\n"; str += "PhoneType = " + tm.getPhoneType() + "\n"; str += "SimCountryIso = " + tm.getSimCountryIso() + "\n"; str += "SimOperator = " + tm.getSimOperator() + "\n"; str += "SimOperatorName = " + tm.getSimOperatorName() + "\n"; str += "SimSerialNumber = " + tm.getSimSerialNumber() + "\n"; str += "SimState = " + tm.getSimState() + "\n"; str += "SubscriberId(IMSI) = " + tm.getSubscriberId() + "\n"; str += "VoiceMailNumber = " + tm.getVoiceMailNumber() + "\n"; TextView sys = (TextView) findViewById(R.id.sys); sys.setText(str); }
手机SIM卡的IMSI,ICCID与Ki码
我们一般用的手机sim卡里面有三组数值是关键的:IMSI、ICCID和ki,有了这三组数值,你的sim卡就能被复制。市面上卖的的一卡多号其实就是通过读取sim卡这三组数值,将他们写到一张特殊的卡上,从而达到复制的目的。IMSI和ICCID可以直接读取,ki却是加密的。
说到这里就不能不简单介绍一下SIM卡,SIM卡是一种智能卡片,里面有个非常简单的CPU和一点NVRAM,可以存储和读出数据,还可以进行一些运算。卡里面有很多内容,不过只介绍和加密相关的。每张SIM卡里面一般都存着一个全球唯一的标志号,叫做IMSI,这个是用来唯一标识你SIM卡的,手机在开机时候会从卡里面读出这个号发给移动网络,移动那里有一个很大的数据库,描述了IMSI和手机号的对应关系,于是网络就知道你的手机号是多少了(如果你手机卡丢了去补,新补来的卡IMSI和原有的不同,而移动数据库那里将你原来的手机号指向新的IMSI,旧的卡就再也不能用了)除了IMSI,还有16个字节的密钥数据,这个数据是无法通过 SIM 卡的接口读出的,通常称为Ki,Ki在移动网络那边也保存了一份。
在手机登录移动网络的时候,移动网络会产生一个16字节的随机数据(通常称为RAND)发给手机,手机将这个数据发给SIM卡,SIM卡用自己的密钥Ki和RAND做运算以后,生成一个4字节的应答(SRES)发回给手机,并转发给移动网络,与此同时,移动网络也进行了相同算法的运算,移动网络会比较一下这两个结果是否相同,相同就表明这个卡是我发出来的,允许其登录。这个验证算法在GSM规范里面叫做A3,m=128 bit,k=128 bit,c=32 bit,很显然,这个算法要求已知m和k可以很简单的算出c,但是已知m和c却很难算出k 。A3算法是做在SIM卡里面的,因此如果运营商想更换加密算法,他只要发行自己的SIM卡,让自己的基站和SIM卡都使用相同的算法就可以了,手机完全不用换。
在移动网络发送RAND过来的时候,手机还会让SIM卡对RAND和Ki计算出另一个密钥以供全程通信加密使用,这个密钥的长度是64 bits, 通常叫做Kc,生成Kc的算法是A8,因为A3和A8接受的输入完全相同,所以实现者偷了个懒,用一个算法同时生成SRES和Kc。
在通信过程中的加密就是用Kc了,这个算法叫做A5,因为A5的加密量很巨大,而且SIM卡的速度很慢,因此所有通信过程中的加密都是在手机上面完成的,这样一来,除非天下所有GSM手机都至少支持一种相同的A5算法,否则就没法漫游了,这时候运营商和设备商的懒惰又体现出来了,全世界目前只有一种通用的A5算法,没有其他的,这个算法就是和Kc 的8字节序列进行简单的循环XOR,再和报文序号做个减法。
现在说说为啥手机卡可以被复制。从前面的介绍里面我们知道,要完成一次登录过程,IMSI和Ki是必不可少的,A3算法也需要知道,这其中IMSI是直接可读的,但是A3算法和存在你的卡里面的数据,都是不知道的,手机只是简单的把RAND给SIM卡,SIM卡把算好的数据返回。实际设备中使用的A3算法被作为高级商业机密保护起来。但是世界上没有不透风的q1an9,在1998还是1999年的时候,有人从哪里偷到了几页纸的相关文档,然后把这文档输入了电脑。后来这个文档落到了加州伯克力几个教授手里面。这个文档里面缺少一些东西,而且还有写错的地方,这几个教授们拿一个SIM卡比对了一阵子,把缺的补上了,错的也给修正了,于是这个算法就成为了世人皆知的秘密。这个算法又被叫做Comp128,他同时生成SRES和Kc。
光有了算法还是不能够得到在SIM卡里面保存的Ki,理论上面是可以把SIM卡拆了,然后把芯片接到特殊设备上面来读出Ki,但是这个听起来就像用小刀在硬盘上面刻操作系统一样不靠谱。于是很多有志之士就开始了对Comp128 算法的攻击,在一开始大家想到的肯定是穷举,不过这个GSM的设计者也想到了,SIM 卡里面有个逻辑是一共只能查询2^16次左右,之后卡会自杀,让破解者啥都得不到。因此研究者们试图在可以接受的次数之内通过构造特定明文和分析输出秘文来分析出Ki的值,结果还真被大家发现出来了一些。IBM的一个小组甚至用6次查询就可以彻底解出Ki,当然现在外面卖的那种机器肯定没有这么牛。
随着时间的推移,针对Comp128的破解算法越来越成熟,SIM复制设备也越来越多,运营商们终于坐不住了。很多运营商都开始发行Comp128 v2加密算法的卡了。Comp128 v2算法是GSM协会在v1被攻破以后,迅速在v1上面修改得来的结果,据说比较好的解决了v1算法中的弱点,当然,这个算法像v1一样,还是不公布于众的,而且到现在也没有人公布出来。这样一来,基本就没法解了。
中国的运营商同样也遇到了SIM卡被复制问题,这里我主要讲讲中国移动。大约从2005年下半年发行的卡开始,已经不能直接用simscan等软件读出ki,但是,这并不是真正v2卡。有消息指出,v2卡虽然解决了能被复制的漏洞,但是兼容性和稳定性方面不尽人意。聪明的中国移动当然不会不管这个问题,它在成熟的v1卡基础上,自己做了小小的修改,巧妙的躲避了simscan等软件的扫描,达到不被复制的目的。这种卡我们暂时称作v0卡。v0卡是中国移动自己设计出来,据说是改变了原来ki的配对规律,使常规的扫描无法读出ki。本文的核心内容,就是讲述如何读出v0卡的ki。
下面提供一个关键的规律表:
拥有第0对KI时,解剩下的KI顺序为:4,2,6,1,5,3,7
拥有第1对KI时,解剩下的KI顺序为:5,3,7,0,4,2,6
拥有第2对KI时,解剩下的KI顺序为:6,0,4,1,5,3,7
拥有第3对KI时,解剩下的KI顺序为:7,1,5,0,4,2,6
拥有第4对KI时,解剩下的KI顺序为:0,2,6,1,5,3,7
拥有第5对KI时,解剩下的KI顺序为:1,3,7,0,4,2,6
拥有第6对KI时,解剩下的KI顺序为:2,0,4,1,5,3,7
拥有第7对KI时,解剩下的KI顺序为:3,1,5,0,4,2,6