作者: Gertificate


SD卡硬件本身提供了加密的功能

----------------------------------

 目前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实现,其数据包中包括该命令中所有的信息。

 

Byte

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

0

 

Erase Card

Lock/UnLock

ClrPwd

SetPwd

1

Psw_Length

2

Pwd Data

 

 

 

PwdLen+1

 

 

擦除:此位置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长度。