(本项目系组员Quix独立完成,涉及软件著作权,故仅对该项目做简要说明)
XRFP1相关实现思路
1.各扇区数据通过自动填充,分组,后经RSA加密算法进行加密。
2.扇区密钥根据UID自动生成
3.RSA解密数据后仍然需要读取正确的交易次数数据来进行最终数据获取
4.存在基于交易次数的不断修正的干扰扇区
5.采用UID对应函数,实现了使用不同的10组以上的公钥,密钥对数据进行加解密
6.硬件采用RC522芯片与Atmega328p-au方案
7.协议保存数据包括:金钱1,金钱2,持卡人姓名,卡片协议名与版本,申请日期,卡片持有人权限,交易次数等
XRFP1 Copyright @ZQWEI Quix All right reserved.
部分程序(非保密部分)
long idcode(long l, long m, long n) { //蒙哥马利法解算幂模方程 a^c≡b(mod n)
long a1, m1, n1, a2, m2, n2;
long i, j, cnt, quotient, tmp, s1 = 1, s2 = 1;
long mm[20];
unsigned long lRet;
a1 = a2 = l;
m1 = m2 = m;
n1 = n2 = n;
quotient = m1;
for (i = 0; quotient != 0; i++) {
mm[i] = quotient % 2;
quotient = quotient / 2;
}
j = i;
for (i = 0; i < j; i++) {
if (mm[i] == 1) {
s1 = (s1 * a1) % n1;
}
a1 = (a1 * a1) % n1;
}
lRet = s1;
return lRet;
}
void keycode() { //根据UID生成2个秘钥
int idanss[4];
for (int i = 0; i < 4; i++) {
idanss[i] = keymap(id[i]);
}
b = idcode((id[0] + id[3]) * 10, idanss[0], RSApublickey);
spread(b);
for (int i = 0; i < 3; i++) {
KeyB[i] = a[i];
}
b = idcode((id[1] + id[2]) * 10, idanss[2], RSApublickey);
spread(b);
for (int i = 0; i < 3; i++) {
KeyB[i + 3] = a[i];
}
b = idcode((id[0] + id[1]) * 10, idanss[1], RSApublickey);
spread(b);
for (int i = 0; i < 3; i++) {
KeyA[i] = a[i];
}
b = idcode((id[3] + id[2]) * 10, idanss[3], RSApublickey);
spread(b);
for (int i = 0; i < 3; i++) {
KeyA[i + 3] = a[i];
}
Serial.print(“KeyA:”);
for (int i = 0; i < 6; i++) {
Serial.print(KeyA[i]);
Serial.print(” “);
}
Serial.println();
Serial.print(“KeyB:”);
for (int i = 0; i < 6; i++) {
Serial.print(KeyB[i]);
Serial.print(” “);
}
}
void mifarewrite(byte block, byte *array, int a) {
MFRC522::StatusCode status;
// Write data to the block
Serial.print(F(“Writing data into block “)); Serial.print(block);
Serial.println(F(” …”));
dump_byte_array(array, 16); Serial.println();
status = (MFRC522::StatusCode) mfrc522.MIFARE_Write(block, array, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F(“MIFARE_Write() failed: “));
Serial.println(mfrc522.GetStatusCodeName(status));
}
Serial.println();
}
void mifareread(byte block, byte *array, int a) {
MFRC522::StatusCode status;
status = mfrc522.MIFARE_Read(block, array, a);
if (status != MFRC522::STATUS_OK) {
Serial.print(F(“Reading failed: “));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
}