目录
1引言 2
1.1锁的现状及瓶颈 2
1.2研究目的 4
2研究内容 4
2.1运用运行方案设计 4
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)磁卡锁:
德国和美国的两名研究员宣布,他们已利用电脑成功破解了荷兰芯片制造商恩智浦(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盾有很大的相似之处。钥匙部分的单片机先从独立的时钟里读取时间信息,经过加密后发送到锁上,锁上的单片机经过解码后如果与锁上的时间信息相同,则开锁。密码每分钟会改变一次。
2.2装置逻辑图
2.3装置硬件,原件结构
2.3.1硬件
图一锁正面 图二锁反面 图三钥匙反面
(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
图6