|
飞利浦的M1卡由于它的高安全性在市场上得到广泛应用,比如我们乘车用的公交卡,学校和企业食堂的饭卡等等.它共有1K字节的EEPROM,共分成16个扇区,而且每个扇区有独立的密匙(6个字节的密码),在通信过程中首先要验证密匙才能读写数据.它的关键技术在于密匙的验证采用三重加密的DES算法,(即:读写器与卡之间传送的密匙是通过随机数加密的),不象早期的EMID卡和atmel的T557卡都是明码传输,所以在开始一度认为是最安全的卡,被广泛的当做电子钱包使用.兄弟们那里面放的就是钱啊!
自从08年以后有人成功破_解了M1卡,曾一度造成恐慌.可想而知它的危害是有多大.也就是说别人随便就可以复制你的卡拿去消费,甚至自己就可以写数据往里面充值,08年前的NXP和08年后的NXP在世人眼里已经大不一样了.至于破_解细节也不是我们一般人能够轻易掌握的.大概原理也就是通过天线截取读写设备对卡进行扣费或充值的码流,然后通过计算分析出它的密码,它的前提是你首先要破_解这种卡的逻辑加密算法,然后通过逆向工程计算出密匙,它的逻辑加密算法只能通过爆力破_解,打开芯片内部观看逻辑电路得到的.呵呵我想复旦微也是这么干才得到M1卡逻辑加密算法的,不然他们怎么能生产出M1卡和基站芯片的(开个玩笑).好了,说了一大堆废话都跑题了,还是回到主题.我也是不经意想到这种方法,但没通过验证.只是把想法贴出来让大家讨论.如果真行的话,那么首先声明不要使用在非法的活动上面,本人慨不负责!
先看下图,我们知道和M1卡通信都是通过专用的基站进行的,这里使用的是FM1702
1702与MCU的接口 (原文件名:SPI接口.JPG)
象这样的芯片有很多种但大体上差不多,并都是兼容的,比如飞利浦的的RC500,RC522.RC530,复旦微的FM1702,1701等等.而且它们和MCU的接口都是常用的串口,有IIC. SPI, UART. 我的想法是即然复杂的逻辑加密算法我们搞不懂但如果我们能得到未加密的明码呢,那不是破_解太简单了吗?你可能在说我是枉想.确实,如果你想截取基站和卡之间的数据流得到明码那真是枉想.但我的想法是MCU和基站之间的串口通信总该是明码吧.我们是不是可以从线路上下手.直接侦听SPI的数据.也就是说首先你要得到一台读写设备和一张卡,然后通过示波器存贮一次扣费操作的整个SPI数据流.如下图:
londkeyr的部分SPI数据 (原文件名:TEK0000.jpg)
这个数据流中一定有某一个扇区的密匙.而且是明码的.如果没有它就不可能完成认证.我们再来看看Load_key程序的流程.:
/****************************************************************/
/*名称: Load_key */
/*功能: 该函数实现把 MCU中的密钥存入FM1702的keyRevBuffer中*/
/*输入: *uncoded_keys:未格式化的原始密钥/
/*输出: True: 密钥装载成功*/
/* False: 密钥装载失败*/
/****************************************************************/
uchar Load_key(uchar *uncoded_keys)
{
uchar temp;
uchar coded_keys[13];
M500HostCodeKey(uncoded_keys, coded_keys);// 转换密钥格式
temp = Command_Send(12, coded_keys, LoadKey);//密钥缓冲区中的密钥存入FM1702的keyRevBuffer中
temp = SPIRead(ErrorFlag) & 0x40;
if (temp == 0x40)
{
return false;//=0
}
return true;//=1
}
密匙是存在uncoded_keys这个BUFFER区共6个字节,在传给FM1702之前要做一个简单的格式转换,并非加密.是通过M500HostCodeKey这个函数实现的;
///////////////////////////////////////////////////////////////////////
// 转换密钥格式
///////////////////////////////////////////////////////////////////////
uchar M500HostCodeKey( uchar *uncoded, uchar *coded)
{
//char status = FM1702_OK;
uchar cnt = 0;
uchar ln = 0;
uchar hn = 0;
for (cnt = 0; cnt < 6; cnt++)
{
ln = uncoded[cnt] & 0x0F;
hn = uncoded[cnt] >> 4;
coded[cnt * 2 + 1] = (~ln << 4) | ln;
coded[cnt * 2 ] = (~hn << 4) | hn;
}
return FM1702_OK;
}
这个函的的功能只是将6个字节的原码拆开成12个字节然后放在coded_keys区,它把每个字节高四位和低四位拆开移位后加上它们的反码.(所以得到密匙后还要一个简单的还原.)
temp = Command_Send(12, coded_keys, LoadKey);//密钥缓冲区中的密钥存入FM1702的keyRevBuffer中
这句才是关键.其实我们需要的也只有这一段数据.它先是通过SPI口发送LoadKey命令(0x19),然后紧跟着就是12个被简单转换了的密匙.看上去好象我们一定要知道它的原程式才可以做到一样,其实也没必要,我只是为了说明才贴上代码.其实我们侦测到数据流后只要找到LoadKey命令0x19那么后面一定就是密匙,如果让人工把SPI时序翻译成数据的话确实要精力,不知有没这种解SPI时序的软件,跟据波形可以直接得到数据.
以上只是我个人的想法,知识有限,望各位高手不吝赐教. |
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|