一、RFID三次认证
阅读器
发送查询口令的命令给应答器应答器
作为应答响应传送所产生的一个随机数RB
给阅读器。
- 阅读器产生一个随机数RA
- 使用共享的密钥K和共同的加密算法 E K E_K EK,算出加密数据块
TOKENAB
,并将TOKENAB传送给应答器。
TOKEN AB = E_k(RA,
RB)
- 使用共享的密钥K和共同的加密算法 E K E_K EK,算出加密数据块
- 应答器接受到TOKENAB后,进行解密
- 将取得的随机数与原先.发送的随机数
RB
进行比较,若一致,则阅读器获得了应答器的确认。
- 将取得的随机数与原先.发送的随机数
- 应答器发送另一个加密数据块
TOKENBA
给阅读器
TOKENBA= Ek(RB1
,RA) - 阅读器接收到TOKENBA并对其解密
- 若收到的随机数与原先发送的随机数
RA
相同,则完成了阅读器对应答器的认证。
- 若收到的随机数与原先发送的随机数
阅读器和应答器都需要存储一些随机数以及其他相关数据,来确保认证的正确性。
阅读器需要存储自己生成的随机数RA以及收到的应答器的随机数RB和RB1
应答器则需要存储收到的阅读器的随机数RA和自己生成的随机数RB和RB1
为了防止重放攻击,这些随机数不能被复用,每次都需要生成新的随机数。
也可以搭配时间戳、MAC、序列号等避免重放攻击。
二、python实现
import random
from sympy import isprime
def modinv(a, m):
"""计算a关于模数m的模反元素"""
def egcd(a, b):
"""扩展欧几里得算法,用于计算最大公约数和系数"""
if a == 0:
return b, 0, 1
else:
g, y, x = egcd(b % a, a)
return g, x - (b // a) * y, y
g, x, y = egcd(a, m)
if g != 1:
# 如果模反元素不存在,则引发异常
raise ValueError("modular inverse does not exist")
else:
# 返回结果,但结果可能是负数,确保最终结果落在[0, m)之间
return x % m
def generate_prime_number(num_digits):
"""生成指定位数的素数"""
while True:
# 生成范围在10^(n-1)到10^n之间的随机数
num = random.randint(10 ** (num_digits - 1), 10 ** num_digits - 1)