目前SD卡在数码产品中的应用是越来越广泛,用户对SD卡的资料存贮隐私保护越来越重视。但如何安全方便的保护数据资料呢?在网上查阅了大量资料,发现少之又少。后来朋友买了一个诺基亚的手机也带SD卡加锁功能,SD加锁之后无法用读卡器识别,也不能被电脑格式化,对普通用户来讲已经是非常安全了。我仔细查阅了SD卡的相关技术资料后,终于明白了SD卡加密的技术实现思路。原来SD卡有专门的加密加锁操作方式,通过SPI访问方式发加密命令字,就可以实现加密功能,加密之后,SD卡在上电的过程中如果没有密码,就会无法访问该SD卡。这也是SD卡之所以被称为“安全数字卡”的原因之一。
研究了几天,终于实现了SD卡加解锁功能!主要注意几点:
1 密码长度Pwd_len要包含新/旧密码长度,还有顺序不能错;
2 传cmd42的时候要同时将参数传进去,如0X05;
3 加锁之前要用cmd16设数据块长度,数据块长度不是SPEC上说的一定是512字节,只要大于密码数据区的长度就好,最后要恢复到512就可以了;
4设完之后可以得到0xe5的响应,表示数据已经接受,用CMD13可以读SD状态得到LOCK标志位已置位,为0X01。
SD卡具有安全加密功能,内置128bit加密位,在加密状态下,用户需提供密码才可以访问卡内的数据。
在卡上电时,若卡包含密码,卡自动进入锁定状态,读写命令均返回错误,以保护卡内容不被读出及修改。
密码设置功能由CMD42实现,其数据包中包括该命令中所有的信息。
擦除:此位置1时,卡的密码和内容会被强制擦除,在遗忘密码时可使用此功能。
锁定/解锁:此位置1时,表示命令结束后状态为锁定,为0,表示卡解锁。
清除密码:此位置1,表示清除卡的旧密码,此时数据中必须包含旧密码的正确内容。
加密:此位置1,表示设置卡的新密码,数据中必须包含新密码内容;更改密码时,新密码紧跟随旧密码内容。
注:在CMD42命令之前,首先要使卡工作在传输状态,在SD模式下可使用CMD7进行状态转换,在SPI模式下,可使用初始化序列进行状态切换。
在任意刻,主机可以通过CMD13命令读取卡的内部状态,判断其锁定状态。定义如下:
<!--[if !vml]-->图略<!--[endif]-->
bit0置1表示卡处于锁定状态。
1、设置密码
使用CMD16设置Block长度为密码长度为PWD_LEN+2;
发送CMD42命令:0x6A,0x00,0x00,0x00,0x00,0x95;
发送命令数据:0x01,LEN,CMD_DATA0,CMD_DATA1……,0xFF,0xFF;
使用CMD16恢复原Block长度。
2、清除密码
使用CMD16设置Block长度为PWD_LEN+2;
发送CMD42命令:0x6A,0x00,0x00,0x00,0x00,0x95;
发送命令数据:0x02,LEN,CMD_DATA0,CMD_DATA1……,0xFF,0xFF;
使用CMD16恢复原Block长度。
3、卡的锁定、解锁
使用CMD16设置Block长度为PWD_LEN+2;
发送CMD42命令:0x6A,0x00,0x00,0x00,0x00,0x95;
发送命令数据:0x04,LEN,密码[LEN]……,0xFF,0xFF;
使用CMD16恢复原Block长度。
4、修改密码
使用CMD16设置Block长度为OLD_PWD_LEN+NEW_PWD_LEN+2;
发送CMD42命令:0x6A,0x00,0x00,0x00,0x00,0x95;
发送命令数据:0x05,LEN,旧密码[n],新密码[m]……,0xFF,0xFF;
使用CMD16恢复原Block长度。
5、卡擦除
使用CMD16设置Block长度为1;
发送CMD42命令:0x6A,0x00,0x00,0x00,0x00,0x95;
发送命令数据:0x08,0xFF,0xFF;
使用CMD16恢复原Block长度。