新型时间变量电子锁

目录

摘要 2

1引言 2

1.1锁的现状及瓶颈 2

1.2研究目的 4

2研究内容 4

2.1运用运行方案设计 4

图1

2.2装置逻辑图 4

2.3装置硬件,原件结构 4

2.4研究遇到的问题和解决方法 6

3总结与讨论 6

3.1先进性及独特之处 6

3.2与同类项目比较 6

4成品总结 7

5展望 7

7参考文献 7

8附录 7

摘要

从人类几千年前第一次发明了锁以来,锁已经经历了翻天覆地的变化,从机械锁到电子锁各种锁具层出不穷。然而,目前世界上的锁,或多或少存在一些漏洞或缺点。

根据目前市面上不同锁具的安全问题,开发出可以防止所有现有的撬锁工具/软件攻击的新型锁具,并且产品必须具有成本低,安全性高,不依赖于人体器官,使用寿命长等特点。产品可以广泛应用于家庭防盗门,保险柜,汽车门等场所。

本产品由Arduino单片机、时钟、NFC模块、显示屏、按钮和步进电机组成。

使用Arduino单片机因此单片机有这一特点:它是一款便捷灵活、方便上手的开源电子原型平台, Arduino,是一个基于开放原始码的软硬件平台。而在我这个项目中我使用的是Arduino Mega2560这钟开发板。这种开发板的优点是串口多,这样可以让我在一块板上添加更多的模块。

NFC模块:在单一芯片上结合感应式读卡器、感应式卡片和点对点的功能,能在短距离内与兼容设备进行识别和数据交换。用2个NFC模块进行数据的传输。

1 引言

1.1锁的现状及瓶颈

从人类几千年前第一次发明了锁以来,锁已经经历了翻天覆地的变化,从机械锁到电子锁各种锁具层出不穷。然而,目前世界上的锁,或多或少存在一些漏洞或缺点。下面就是一些例子。

1.1.1物理锁

    按照安全级别,目前市面上流行的防盗门锁大致分为A、B、C三类,市民普遍使用的是A级锁和B级锁。而针对不同类型的锁,小偷也亮出了“十八般开锁武器”。

    A级锁PK铁片开锁不超过1分钟

    现场演示:刘至祥说,A级锁包括一字锁和十字锁,这种锁安全级别最低,防盗性能最差。他作了一个实验,用一个铁钩插进已经上锁的一字锁孔,轻轻搅动,然后再用一个铁片插入锁孔,转动两下,门锁就被打开了,整个过程只用了4秒钟。

    防范指南:A级锁是小偷的重点目标。使用铁钩、铁片就能打开,最多不超过1分钟,最快一两秒。民警建议,应及时将A级锁锁芯更换为防盗性能较好的B级锁。此外,可在门上加装一个插销。

    B级锁PK锡纸和撞枪开锁不超过5分钟

    现场演示:刘至祥说,B级锁主要分为单排和双排弹珠锁,单排和双排月牙锁,单排带曲线锁和双排带曲线锁6种。作为A级锁的升级版,B级锁弹子下的口径较小,铁片拉钩等工具打不开,开锁难度增加。不过,B级锁也不是100%牢靠。

    刘至祥用锡箔纸,简单加工后塞进专用钥匙中,插入锁孔,转动五六下后,不超过5秒钟就开启B级锁。而针对做工较精良的门锁,他用专用撞枪,10秒钟内即搞定。

    防范指南:目前大多数小区都使用的是B级锁,市民可以升级更换成可防御一切技术性开启的超B级锁。可在有备案的正规锁具公司购买,价格只需一两百元。

    C级锁目前相对最安全几乎无开锁工具能破解

    目前,相对最安全的是C级锁。刘至祥说,这类锁以双控机电锁为主,另包括指纹锁等。

这种锁的核心是芯片识别,“即使门里的锁芯被攻破,要打开门的话,钥匙里的芯片还要识别门里的芯片。也就是说,必须要破坏锁体才能开门。”刘至祥说,仿造芯片的成本太高,所以现在几乎没有一种技术性开锁工具能够破解。这种锁价格在1000元左右

1.1.2电子锁

(1)指纹锁:

指纹收集技能主要有光学收集技能,半导体收集技能,超声波收集技能三种.超声波收集技能尽管技能高超,但由于本钱高且处于实验期间,在指纹锁识别系统中几乎没有运用.半导体收集技能诞生于1998年,可刹那间捕捉与及时调整图画,比光学收集的图画准确,但容易遭到静电,汗液,污物,手指磨损等状况的影响,致使传感器取不到图画,乃至会被损坏;且不耐磨损,寿数较短,因而,其运用范畴对比小.而光学收集技能是最陈旧的指纹收集技能,阅历了长时间实践应用的检测,能接受必定程度温度改变,稳定性好,识别活络,且其收集仪一般选用钢化玻璃,非常耐磨损,可有用延伸运用寿数.那么,光学指纹头是否可以被成功复制呢?答案是可以的。但这就需要主人积极配合别人取模,如《好奇实验室》橡皮泥破解指纹视频中一样,主人乖乖把手指按在橡皮泥上几分钟让别人取得指纹模型,然后用硅胶倒模制作出与主人相同的指纹,如此便可成功破解指纹锁了。

图2

(2)磁卡锁:

德国和美国的两名研究员宣布,他们已利用电脑成功破解了荷兰芯片制造商恩智浦(NXP)的Mifare经典芯片(简称MI芯片)的安全算法,但出于公共利益考虑没有对外公开技术细节。此后,欧洲和美国又数次传出个人成功破解MI芯片的消息,互联网上甚至已有人出售MI芯片的破解软硬件。

  “目前全世界掌握IC卡芯片技术的厂商只有三四家,其中恩智浦的MI芯片是应用最广泛的。”赛迪顾问半导体研究中心咨询师李志中表示,我国约有1.4亿张IC卡、包括85%%的公交卡都采用MI芯片。而在全球,这种芯片的使用量多达10亿张。

(3)蓝牙锁

据国外媒体报道,在DEF CON黑客大会上,一名安全研究人员表示,许多低功耗智能锁被未经授权用户解锁,而厂商似乎并不打算对此作出行动。电力工程师 Anthony Rose表示,他和小伙伴测试了16个蓝牙智能锁,其中有12个可无线破解。这些锁的品牌也已经被公布出来,比如Quicklock、iBlulock、Plantraco、Ceomate、 Elecycle、 Vians、Okidokey 和Mesh Motion,这些锁被破解的难度不高,介意容易和中等之间。

(以上内容均来自网络)

1.2研究目的

根据目前市面上不同锁具的安全问题,开发出可以防止所有现有的撬锁工具/软件攻击的新型锁具,并且产品必须具有成本低,安全性高,不依赖于人体器官,使用寿命长等特点。产品可以广泛应用于家庭防盗门,保险柜,汽车门等场所。

2研究内容

2.1运用运行方案设计

产品的灵感来源于银行的U盾。

U盾:

进行网上交易时,银行会向你发送由时间字串,地址字串,交易信息字串,防重放攻击字串组合在一起进行加密后得到的字串A,你的U盾将根据你的个人证书对字串A进行不可逆运算得到字串B,并将字串B发送给银行,银行端也同时进行该不可逆运算,如果银行运算结果和你的运算结果一致便认为你合法,交易便可以完成,如果不一致便认为你不合法,交易便会失败。

理论上,不同的字串A不会得出相同的字串B,即一个字串A对应一个唯一的字串B;但是字串B和字串A无法得出你的数字证书,而且U盾具有不可读取性,所以任何人都无法获得你的数字证书。并且银行每次都会发不同的防重放字串(随机字串)和时间字串,所以当一次交易完成后,刚发出的B字串便不再有效。综上所述,理论上U盾是绝对安全的****注意是理论上发生伪造概率大约为2的80次方分之一。

本产品原理与U盾有很大的相似之处。钥匙部分的单片机先从独立的时钟里读取时间信息,经过加密后发送到锁上,锁上的单片机经过解码后如果与锁上的时间信息相同,则开锁。密码每分钟会改变一次。

图3

2.2装置逻辑图

2.3装置硬件,原件结构

2.3.1硬件

图4

图一锁正面 图二锁反面 图三钥匙反面

(1)、锁部分:由Arduino单片机、时钟、NFC模块、显示屏、按钮和步进电机组成(如图一、图二)。

使用Arduino单片机因此单片机有这一特点:它是一款便捷灵活、方便上手的开源电子原型平台, Arduino,是一个基于开放原始码的软硬件平台。而在我这个项目中我使用的是Arduino Mega2560这钟开发板。这种开发板的优点是串口多,这样可以让我在一块板上添加更多的模块。

NFC模块:在单一芯片上结合感应式读卡器、感应式卡片和点对点的功能,能在短距离内与兼容设备进行识别和数据交换。用2个NFC模块进行数据的传输。

、钥匙部分:由Arduino单片机,时钟,NFC通信模块,显示屏组成。

2.3.2软件

(1)、锁部分的软件分为五个部分,分别是时钟部分、NFC读取部分、解码部分、显示屏部分、和步进电机部分。

时钟部分:读取时钟上的时间,并将其转化成显示屏上显示的时间。

NFC读取部分:当钥匙接近时读取NFC tag上的密文,将其赋予变量“X”。并将变量“isNFCSuccess”设为1(表示已经收到了密文)。

解码部分:通过AES重新将解收到的密文解密,并比对时钟,如果密码正确,则将变量“isCheckSuccess”设为1(表示密文正确)。

显示部分:开始时显示"Waiting for NFC tag!"和时间。当“isCheckSuccess”等于1时,会将接收到的密文转化为字符并显示出来,还会显示"Receive Successfully!"。

步进电机部分:当“isCheckSuccess”为0时,舵机转到0度(表示门已经锁上了),当它为1时,舵机转到90度(表示门锁打开了)。

(2)、钥匙部分部分的软件分为四个部分,分别是时钟部分、NFC读取部分、加密部分和显示屏部分。

时钟部分:同上。

加密部分:将时间通过AES加密。

NFC部分:将加密好的密文写入NFC里。

显示屏部分:同上。

AES加密:输入是一个128位分组。这些分组被描述成4×4的字节方阵,经过字节代替、行移位、列混淆、轮密钥加这四个步骤进行三轮加密。它具有可逆性的特点。这样钥匙上加密的时间信息可以在锁上解密出来并进行确认。 2.4研究遇到的问题和解决方法

问题:单片机内置时钟断电后不再计时。解决方案:使用外置时钟(有由额外电源供电)。

问题:时钟时间一长会出现误差。解决方案:设计的外置时钟可以取下,并换上经过校准的新时钟。

问题:锁的单片机会没电,门无法开启。解决方案:锁上装有手摇式发电机,没电时可以发电。

3总结与讨论

3.1先进性及独特之处

本品的独特之处在于:(1)开锁时间快

(2)采用了时间变量作为密码,密码会随着时间的变化而变化,安全性大大提高。

3.2与同类项目比较

与市面上的其他锁具相比,本产品具有成本低、被破解可能性低、不依靠于人体器官、无法远程破解、钥匙数量不受限制等特点。

成本低:经估算如进行专业软件和硬件设计可以将每件产品的成本降到200元以下。

破解可能性低:密文为128位,约有3.4*10^38种可能性。而且每分钟密码改变一次。单片机每秒钟才读取一次密码。被破解的可能性几乎为零,除非运气好到逆天直接猜对。

不依靠于人体器官:不会因为身体器官的损坏而出现无法开门的问题。

4展望

虽然现在有法律规定电子锁必须装有物理开锁方式,但我认为随着科技的发展,物理锁终归会迎来极限。迟早会出现可以破解所有物理锁的装置(比如发明便携式X光机,瞬间看透锁具结构),纯电子锁迟也早会出现。

我的作品如果进行专业软件和硬件设计,就可以运用到千家万户,就可以防贼防盗。再也没有能通过技术手段破开你家的锁。我的作品还可以运用到保险柜等场所。如果出现时间差错过大的现象,厂价可以回收旧的时间模块,在校准后还给使用者。

7 参考文献

[1]Massimo Banzi.《爱上Arduino》.于欣龙,译.北京:人民邮电出版社,2011.

8 附录

程序:锁部分

/*******************Port Interface**************

Arduino Mega OLED 128x64

+5V VCC

GND GND

SCL SCL

SDA SDA

/*******************Port Interface**************

Arduino Mega DS3231

+5V VCC

GND GND

SCL SCL

SDA SDA

/*******************Port Interface**************

Arduino Mega NFC Module

+5V VCC

GND GND

D52 SCK

D50 MISO

D51 MOSI

D10 SS

*/

#include

#include "DS3231.h"

#include "U8glib.h"

#include

#include

#include

#include

#include

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI

DS3231 RTC;

PN532_SPI pn532spi(SPI, 10);

NfcAdapter nfc = NfcAdapter(pn532spi);

DateTime dateTime;

String currentTime;

unsigned char displayTime[20];

AES AesEncryption;

byte *key = (unsigned char*)"huangsenhong";

byte checkPlain[12],originPlain[12];

unsigned char displayPlain[12];

byte initialVector[N_BLOCK];

byte cipher[16];

unsigned char displayCipher[17],receiveCipher[17];

unsigned long long int my_iv = 1234567;

int isNFCSuccess = 0;

int isCheckSuccess = 0;

void setup()

{

Serial.begin(9600);

Wire.begin();

RTC.begin();

nfc.begin();

}

void loop ()

{

Time2Char();

NFC_Receive();

Decryption(128);

u8g.firstPage();

do {

draw();

} while( u8g.nextPage());

delay(1000);

}

void Time2Char()

{

dateTime = RTC.now(); //get the current date-time

currentTime = dateTime.year();

if(dateTime.month()<10)

currentTime = currentTime+"/0"+dateTime.month();

else

currentTime = currentTime+'/'+dateTime.month();

if(dateTime.date()<10)

currentTime = currentTime+"/0"+dateTime.date();

else

currentTime = currentTime+'/'+dateTime.date();

if(dateTime.hour()<10)

currentTime = currentTime+" 0"+dateTime.hour();

else

currentTime = currentTime+' '+dateTime.hour();

if(dateTime.minute()<10)

currentTime = currentTime+":0"+dateTime.minute();

else

currentTime = currentTime+':'+dateTime.minute();

if(dateTime.second()<10)

currentTime = currentTime+":0"+dateTime.second();

else

currentTime = currentTime+':'+dateTime.second();

currentTime.toCharArray(displayTime,currentTime.length()+1);

Serial.print("originPlain:");

for(int i = 5;i<16;i++){

originPlain[i-5] = displayTime[i];

}

originPlain[11] = '\0';

Serial.println((char*)originPlain);

}

void draw(void) {

u8g.setFont(u8g_font_gdr9);

if(isCheckSuccess){

u8g.drawStr( 0, 15, "Password Matching!");

}

else u8g.drawStr( 0, 15, displayTime);

u8g.drawStr(0, 30, "C: ");

u8g.drawStr(0, 45, "Check: ");

if(isNFCSuccess) {

u8g.drawStr(0, 60, "Receive Successfully!");

u8g.drawStr(15, 30, displayCipher);

u8g.drawStr(40, 45, displayPlain);

}

else u8g.drawStr(0, 60, "Waiting for NFC tag!");

}

void Decryption(int bits)

{

AesEncryption.iv_inc();

unsigned long ms = micros ();

AesEncryption.set_IV(my_iv);

AesEncryption.get_IV(initialVector);

AesEncryption.do_aes_decrypt(cipher,16,checkPlain,key,bits,initialVector);

Serial.print("Encryption took: ");

Serial.println(micros() - ms);

ms = micros ();

isCheckSuccess = 1;

for(int i=0;i<11;i++){

displayPlain[i] = checkPlain[i];

if(originPlain[i]!=checkPlain[i]) isCheckSuccess = 0;

}

displayPlain[11] = '\0';

Serial.print("displayPlain:");

Serial.println((char*)displayPlain);

}

void NFC_Receive()

{

if (nfc.tagPresent()) {

NfcTag tag = nfc.read();

Serial.println(tag.getTagType());

String value = tag.getUidString();

Serial.print("UID: ");Serial.println(value);

if (tag.hasNdefMessage()) // every tag won't have a message

{

NdefMessage message = tag.getNdefMessage();

NdefRecord record = message.getRecord(0);

record.getPayload(receiveCipher);

isNFCSuccess = 1;

for (int i = 1; i < 17; i++) {

displayCipher[i-1] = 33+receiveCipher[i]%93;

cipher[i-1] = receiveCipher[i];

}

displayCipher[16] = '\0';

Serial.print("receiveCipher: ");

for (int i = 0; i < 16; i++) {

Serial.print(char(cipher[i]));

}

Serial.println();

Serial.print("displayCipher: ");

Serial.println((char*)displayCipher);

}

else isNFCSuccess = 0;

}

else isNFCSuccess = 0;

}

钥匙部分

/*******************Port Interface**************

Arduino Mega OLED 128x64

+5V VCC

GND GND

SCL SCL

SDA SDA

/*******************Port Interface**************

Arduino Mega DS3231

+5V VCC

GND GND

SCL SCL

SDA SDA

/*******************Port Interface**************

Arduino Mega NFC Module

+5V VCC

GND GND

D52 SCK

D50 MISO

D51 MOSI

D10 SS

*/

#include

#include "DS3231.h"

#include "U8glib.h"

#include

#include

#include

#include

#include

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI

DS3231 RTC;

PN532_SPI pn532spi(SPI, 10);

NfcAdapter nfc = NfcAdapter(pn532spi);

DateTime dateTime;

String currentTime;

unsigned char displayTime[20];

AES AesEncryption;

byte *key = (unsigned char*)"huangsenhong";

byte plain[12];

byte checkPlain[12];

byte initialVector[N_BLOCK];

byte cipher[16];

unsigned char displayCipher[17],OriginCipher[17];

unsigned long long int my_iv = 1234567;

int isNFCSuccess = 0;

void setup()

{

Serial.begin(9600);

Wire.begin();

RTC.begin();

nfc.begin();

}

void loop ()

{

Time2Char();

Encryption(128);

NFC_Send();

u8g.firstPage();

do {

draw();

} while( u8g.nextPage());

delay(1000);

}

void Time2Char()

{

dateTime = RTC.now(); //get the current date-time

currentTime = dateTime.year();

if(dateTime.month()<10)

currentTime = currentTime+"/0"+dateTime.month();

else

currentTime = currentTime+'/'+dateTime.month();

if(dateTime.date()<10)

currentTime = currentTime+"/0"+dateTime.date();

else

currentTime = currentTime+'/'+dateTime.date();

if(dateTime.hour()<10)

currentTime = currentTime+" 0"+dateTime.hour();

else

currentTime = currentTime+' '+dateTime.hour();

if(dateTime.minute()<10)

currentTime = currentTime+":0"+dateTime.minute();

else

currentTime = currentTime+':'+dateTime.minute();

if(dateTime.second()<10)

currentTime = currentTime+":0"+dateTime.second();

else

currentTime = currentTime+':'+dateTime.second();

currentTime.toCharArray(displayTime,currentTime.length()+1);

Serial.print("Plain:");

for(int i = 5;i<16;i++){

plain[i-5] = displayTime[i];

}

plain[11] = '\0';

Serial.println((char*)plain);

}

void draw(void) {

u8g.setFont(u8g_font_gdr9);

u8g.drawStr( 0, 15, displayTime);

u8g.drawStr(0, 30, "C:");

u8g.drawStr(15, 30, displayCipher);

u8g.drawStr(0, 45, "Plain: ");

u8g.drawStr(40, 45, plain);

if(isNFCSuccess) u8g.drawStr(0, 60, "Send Successfully by NFC!");

else u8g.drawStr(0, 60, "Waiting for NFC tag!");

}

void Encryption(int bits)

{

AesEncryption.iv_inc();

unsigned long ms = micros ();

AesEncryption.set_IV(my_iv);

AesEncryption.get_IV(initialVector);

AesEncryption.do_aes_encrypt(plain,12,cipher,key,bits,initialVector);

Serial.print("Encryption took: ");

Serial.println(micros() - ms);

ms = micros ();

// byte testCipher[16];

// for(int i=0;i<16;i++){

// testCipher[i] = cipher[i];

// }

for(int i=0;i<16;i++){

displayCipher[i] = 33+cipher[i]%93;

OriginCipher[i] = cipher[i];

}

displayCipher[16] = '\0';

OriginCipher[16] = '\0';

Serial.print("originalCipher: ");

Serial.println((char*)OriginCipher);

Serial.print("displayCipher: ");

Serial.println((char*)displayCipher);

// AesEncryption.set_IV(my_iv);

// AesEncryption.get_IV(initialVector);

// AesEncryption.do_aes_decrypt(testCipher,16,checkPlain,key,bits,initialVector);

// Serial.print("checkPlain:");

// for(int i=0;i<11;i++){

// Serial.print(char(checkPlain[i]));

// }

// Serial.println();

}

void NFC_Send()

{ if (nfc.tagPresent()) {

NdefMessage message = NdefMessage();

message.addUriRecord(OriginCipher);

bool success = nfc.write(message);

if (success) {

isNFCSuccess = 1;

Serial.println("Success. Try reading this tag.");

} else {

Serial.println("Write failed.");

isNFCSuccess = 0;

}

}

else isNFCSuccess = 0;

}

图5

图5

图6

图6