前面我们学习了M1卡扇区、块数据的读写操作,已经涉及到了数据的简单运算处理。那么对数据进行加减1的处理自然也不是问题。可问题是,这里所要说的加减1,不是读->改->回写这种意义上的处理,而是对M1卡进行自动加1或减1操作。这个处理需要遵循一套特定的逻辑,尝尝用于钱包功能,比如公交车自动刷卡功能,每刷一次卡自动减一块的这种场景。在应用场景中还有一个类似的钱包功能,这个数据改变试要根据每次不同的消费额来处理的,并不适用于自动加减1的这种方式。
自动加减1处理中对数据块有特殊要求,它需要使用特殊的值快(Value Block):
字节偏移 | 内容 | 说明 |
0-3 | 当前值 | 4字节有符号整数,采用小端模式存储。例如,数值 0x00000123 在块中存储为 23 01 00 00。 |
4-7 | 当前值取反 | 用于数据校验和防篡改。 |
8-11 | 当前值(备份) | 用于数据校验和防篡改。 |
12-15 | 地址 | 通常存储该块的块号,也用于校验。 |
自动加减1处理中同样像读写处理一样,需要密钥验证。
值块本身的访问权限由其对应的控制位(C1, C2, C3)决定。根据标准权限表,要实现加减操作,通常需要如下配置:
进行加值操作:通常需要验证 Key B。
进行减值操作:通常需要验证 Key A。
如果权限控制位配置错误,加减操作会失败,甚至可能因误操作导致卡片锁定(通常指扇区尾部被改错,导致卡不可用)。
认证通过之后,执行专用的“加减”指令(不是读->改->回写的那种模式),要改成什么值,就由指令控制,利用卡内的算数单元来自动处理了。加值和减值的指令码不一样
这一步完成后,可不意味着加减1的结果就立即生效了,还需要执行“传输”指令,才能完成正常结果的保存。这一步是不能被忽视的这一步传输动作,其实这一步是完成将结果从RC522数据缓冲区的传输个M1卡。
这个传输处理,在执行时可以设定块编号,意味着改变的数据,可以根据需要回填给原来的块,也可以传递该扇区例的其他块(密钥所在块除外)。
前面说过,任何时候都不要试图改变扇区中的控制块,一旦改错了,很有可能废掉这整个M卡。
准备值快时,可以按照以下形式组织一个数据块,

在M1卡中,有16个扇区,每个扇区有3个数据块可用。那么理论上是不是就可以有48个值块可用?这样对每个M1卡,就可以用于不同的支付场景。比如某个值快用于公交卡,某个值块用于旅游景点卡?这样就相当于一卡多用,互不干扰了。
虽然说M1卡可以作为电子钱包使用,但由于其数据可修改属性,以及Key的固定位数小,容易被暴力破解的原因。实际应用上,我觉得还是利用UID属性,与服务器端数据库结合,才更安全、稳妥。
我要赚赏金
