- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Adafruit 的 Arduino Uno 和 nRF8001 板通过蓝牙连接到 Android 手机。我将使用它来锁定和解锁锁,我需要确保只有经过验证的设备才能启动锁定和解锁。我搜索了很多,但找不到一个明确的例子来说明我应该如何验证连接设备。目前,我将 Arduino 连接到锁上,只要连接 Android 手机,就可以锁定和解锁。
我想到的过程如下。
[编辑]我做了很多研究和工作,根据 security.stackexchange 的建议,我决定使用 AES 进行加密。我正在使用 this Arduino library 和 this Android library 我对在 Arduino 和 Android 编程中使用的两个库应该使用什么配置感到有点困惑。
我设置的 Arduino 代码用于测试加密和解密:
#include <AES.h>
AES aes ;
byte key[] =
{
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} ;
byte plain[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} ;
byte my_iv[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
} ;
char PassString[] = "This is hard to believe but true";
char Message[] = "We, the Fairies, blithe and antic Of dimensions not gigantic, Th";
byte cipher [4*N_BLOCK] ;
byte check [4*N_BLOCK] ;
int bits = 128;
int blocks = 4;
void loop ()
{}
void setup ()
{
Serial.begin (9600) ;
Serial.println ("Starting encryption...") ;
byte iv [N_BLOCK] ;
// Pass the key into the byte array
for (int i = 0; i < 32; i++) {
key[i] = PassString[i];
}
print_value ("KEY = ", key, 256) ;
for (int i = 0; i < 64; i++) {
plain[i] = Message[i];
}
// Set Key
byte succ = aes.set_key (key, bits) ;
// Encrypt
for (byte i = 0 ; i < 16 ; i++)
iv[i] = my_iv[i] ;
succ = aes.cbc_encrypt (plain, cipher, blocks, iv) ;
// Decrypt
for (byte i = 0 ; i < 16 ; i++)
iv[i] = my_iv[i] ;
succ = aes.cbc_decrypt (cipher, check, blocks, iv) ;
// Prints the plain, ciper, decrypted, and IV
for (byte ph = 0 ; ph < (blocks == 1 ? 3 : 4) ; ph++)
{
for (byte i = 0 ; i < (ph < 3 ? blocks*N_BLOCK : N_BLOCK) ; i++)
{
byte val = ph == 0 ? plain[i] : ph == 1 ? cipher[i] : ph == 2 ? check[i] : iv[i] ;
Serial.print (val>>4, HEX) ; Serial.print (val&15, HEX) ; Serial.print (" ") ;
}
Serial.println () ;
}
}
char * hex = "0123456789abcdef" ;
void print_value (char * str, byte * a, int bits)
{
Serial.print (str) ;
bits >>= 3 ; //bits goes from decimal 128 to decimal 16
for (int i = 0 ; i < bits ; i++)
{
// of ex. 0xb9 prints b then 9
byte b = a[i] ;
Serial.print (hex [b >> 4]) ;
Serial.print (hex [b & 15]) ;
}
Serial.println () ;
}
我的 Android 程序几乎是从上面的链接中逐字记录的。
我可以让他们都加密和解密他们自己的消息,但他们的设置似乎非常不同,无法相互加密。 Android 代码似乎涉及更多内容,例如创建 key 和盐。这两个库都非常通用,我不确定如何让它们以相同的方式加密。
我有几个问题希望能帮助我解决这个问题:
Arduino 代码中的 PBE 迭代计数在哪里?我真的不看图书馆里的任何东西。我需要自己实现吗?我在库的“test_vectors”示例中看到了一个部分下面的代码。这是迭代吗?
for (int j = 0 ; j < 1000 ; j++)
{
succ = aes.encrypt (plain, cipher) ;
aes.copy_n_bytes (plain, cipher, 16) ;
}
最佳答案
如果你想从 Android 向 Arduino 发送加密消息,你必须确保你在两端使用相同的参数。
我从 Vladimir Klykov 中提取了一些测试向量然后使用 Arduino(使用 AES library )和 Java 进行加密和解密。
两个库都可以设置为 CBC,在两端使用 16 字节的十六进制向量,你不会有填充问题。
Arduino
#include <AES.h>
AES aes ;
//2b7e151628aed2a6abf7158809cf4f3c
byte key[] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
};
//6bc1bee22e409f96e93d7e117393172a
byte plain[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
};
//000102030405060708090A0B0C0D0E0F
byte my_iv[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
};
byte cipher [N_BLOCK] ;
byte check [N_BLOCK] ;
void loop ()
{
}
void setup ()
{
Serial.begin (115200) ;
while (!Serial) ;
Serial.println ("Ready") ;
Serial.print("N_BLOCK: ") ;
Serial.println (N_BLOCK) ;
prekey (128, 2) ;
}
void prekey (int bits, int blocks)
{
byte iv [N_BLOCK] ;
long t0 = micros () ;
byte succ = aes.set_key (key, bits) ;
long t1 = micros()-t0 ;
Serial.print ("set_key ") ; Serial.print (bits) ; Serial.print (" ->") ; Serial.print ((int) succ) ;
Serial.print (" took ") ; Serial.print (t1) ; Serial.println ("us") ;
t0 = micros () ;
if (blocks == 1)
succ = aes.encrypt (plain, cipher) ;
else
{
for (byte i = 0 ; i < 16 ; i++)
iv[i] = my_iv[i] ;
succ = aes.cbc_encrypt (plain, cipher, blocks, iv) ;
}
t1 = micros () - t0 ;
Serial.print ("encrypt") ; Serial.print (" ->") ; Serial.print ((int) succ) ;
Serial.print (" took ") ; Serial.print (t1) ; Serial.println ("us") ;
t0 = micros () ;
if (blocks == 1)
succ = aes.decrypt (cipher, plain) ;
else
{
for (byte i = 0 ; i < 16 ; i++)
iv[i] = my_iv[i] ;
succ = aes.cbc_decrypt (cipher, check, blocks, iv) ;
}
t1 = micros () - t0 ;
Serial.print ("decrypt") ; Serial.print (" ->") ; Serial.print ((int) succ) ;
Serial.print (" took ") ; Serial.print (t1) ; Serial.println ("us") ;
for (byte ph = 0 ; ph < 5 ; ph++)
{
Serial.print(ph == 0 ? "plain: " : ph == 1 ? "key: " : ph == 2 ? "iv: " : ph == 3 ? "enc: " : "dec: ") ;
for (byte i = 0 ; i < (blocks-1)*N_BLOCK ; i++)
{
byte val = ph == 0 ? plain[i] : ph == 1 ? key[i] : ph == 2 ? my_iv[i] : ph == 3 ? cipher[i] : check[i] ;
Serial.print (val>>4, HEX) ; Serial.print (val&15, HEX) ;
}
Serial.println () ;
}
}
Java
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.math.*;
public class Encryptor3 {
public static byte[] hexStringToByteArray(String hexInputString){
byte[] bts = new byte[hexInputString.length() / 2];
for (int i = 0; i < bts.length; i++) {
bts[i] = (byte) Integer.parseInt(hexInputString.substring(2*i, 2*i+2), 16);
}
return bts;
}
public static String byteArrayToString(byte[] byteArray) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < byteArray.length; i++) {
str.append((char) byteArray[i]);
}
return str.toString();
}
public static String byteArrayToHexString(byte[] arg) {
int l = arg.length * 2;
return String.format("%0"+l+"x", new BigInteger(1, arg));
}
public static byte[] encrypt(byte[] key1, byte[] key2, byte[] value) {
try {
IvParameterSpec iv = new IvParameterSpec(key2);
SecretKeySpec skeySpec = new SecretKeySpec(key1, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value);
return encrypted;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static byte[] decrypt(byte[] key1, byte[] key2, byte[] encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(key2);
SecretKeySpec skeySpec = new SecretKeySpec(key1, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(encrypted);
return original;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String toHex(String arg) {
int l = arg.length() * 2;
return String.format("%0"+l+"x", new BigInteger(1, arg.getBytes()));
}
public static String HexStringToString (String arg) {
StringBuilder output = new StringBuilder();
for (int i = 0; i < arg.length(); i+=2) {
String str = arg.substring(i, i+2);
output.append((char)Integer.parseInt(str, 16));
}
return output.toString();
}
public static void main(String[] args) {
// source: http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128
String message = "6bc1bee22e409f96e93d7e117393172a"; // 16 byte = 128 bit key
//String message = toHex("Hello00000000000");
String key1 = "2b7e151628aed2a6abf7158809cf4f3c";
String iv = "000102030405060708090A0B0C0D0E0F";
String match = "7649abac8119b246cee98e9b12e9197d";
System.out.print("message (hex): "); System.out.println(message);
System.out.print("key (hex): "); System.out.println(key1);
System.out.print("iv (hex): "); System.out.println(iv);
System.out.print("match (hex): "); System.out.println(match);
System.out.println();
byte[] enc_message_ba = encrypt(hexStringToByteArray(key1), hexStringToByteArray(iv), hexStringToByteArray(message));
System.out.print("Encrypted (hex): "); System.out.println(byteArrayToHexString(enc_message_ba));
System.out.println();
byte[] dec_message_ba = decrypt(hexStringToByteArray(key1), hexStringToByteArray(iv), enc_message_ba);
System.out.print("Decrypted (hex): "); System.out.println(byteArrayToHexString(dec_message_ba));
}
}
Arduino 输出
在Arduino中安装AES库并照常运行
Ready
N_BLOCK: 16
set_key 128 ->0 took 596us
encrypt ->0 took 1136us
decrypt ->0 took 1548us
plain: 6BC1BEE22E409F96E93D7E117393172A
key: 2B7E151628AED2A6ABF7158809CF4F3C
iv: 000102030405060708090A0B0C0D0E0F
enc: 7649ABAC8119B246CEE98E9B12E9197D
dec: 6BC1BEE22E409F96E93D7E117393172A
Java 输出
将代码放在 Encryptor.java 中,然后从命令行
javac Encryptor.java
java Encryptor
message (hex): 6bc1bee22e409f96e93d7e117393172a
key (hex): 2b7e151628aed2a6abf7158809cf4f3c
iv (hex): 000102030405060708090A0B0C0D0E0F
match (hex): 7649abac8119b246cee98e9b12e9197d
Encrypted (hex): 7649abac8119b246cee98e9b12e9197d
Decrypted (hex): 6bc1bee22e409f96e93d7e117393172a
关于android - Arduino 到 Android 的安全蓝牙连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27652105/
我知道这个问题可能已经被问过,但我检查了所有这些,我认为我的情况有所不同(请友善)。所以我有两个数据集,第一个是测试数据集,第二个是我保存在数据框中的预测(预测值,这就是没有数据列的原因)。我想合并两
在 .loc 方法的帮助下,我根据同一数据框中另一列中的值来识别 Panda 数据框中某一列中的值。 下面给出了代码片段供您引用: var1 = output_df['Player'].loc[out
当我在 Windows 中使用 WinSCP 通过 Ubuntu 连接到 VMware 时,它提示: The server rejected SFTP connection, but it lis
我正在开发一个使用 xml web 服务的 android 应用程序。在 wi-fi 网络中连接时工作正常,但在 3G 网络中连接时失败(未找到 http 404)。 这不仅仅发生在设备中。为了进行测
我有一个XIB包含我的控件的文件,加载到 Interface Builder(Snow Leopard 上的 Xcode 4.0.2)中。 文件的所有者被设置为 someClassController
我在本地计算机上管理 MySQL 数据库,并通过运行以下程序通过 C 连接到它: #include #include #include int main(int argc, char** arg
我不知道为什么每次有人访问我网站上的页面时,都会打开一个与数据库的新连接。最终我到达了大约 300 并收到错误并且页面不再加载。我认为它应该工作的方式是,我将 maxIdle 设置为 30,这意味着
希望清理 NMEA GPS 中的 .txt 文件。我当前的代码如下。 deletes = ['$GPGGA', '$GPGSA', '$GPGSV', '$PSRF156', ] searchquer
我有一个 URL、一个用户名和一个密码。我想在 C# .Net WinForms 中建立 VPN 连接。 你能告诉我从哪里开始吗?任何第三方 API? 代码示例将受到高度赞赏... 最佳答案 您可以像
有没有更好的方法将字符串 vector 转换为字符 vector ,字符串之间的终止符为零。 因此,如果我有一个包含以下字符串的 vector "test","my","string",那么我想接收一
我正在编写一个库,它不断检查 android 设备的连接,并在设备连接、断开连接或互联网连接变慢时给出回调。 https://github.com/muddassir235/connection_ch
我的操作系统:Centos 7 + CLOUDLINUX 7.7当我尝试从服务器登录Mysql时 [root@server3 ~]# Mysql -u root -h localhost -P 330
我收到错误:Puma 发现此错误:无法打开到本地主机的 TCP 连接:9200(连接被拒绝 - 连接(2)用于“本地主机”端口 9200)(Faraday::ConnectionFailed)在我的
请给我一些解决以下错误的方法。 这是一个聊天应用....代码和错误如下:: conversations_controller.rb def create if Conversation.bet
我想将两个单元格中的数据连接到一个单元格中。我还想只组合那些具有相同 ID 的单元格。 任务 ID 名称 4355.2 参与者 4355.2 领袖 4462.1 在线 4462.1 快速 4597.1
我经常需要连接 TSQL 中的字段... 使用“+”运算符时 TSQL 强制您处理的两个问题是 Data Type Precedence和 NULL 值。 使用数据类型优先级,问题是转换错误。 1)
有没有在 iPad 或 iPhone 应用程序中使用 Facebook 连接。 这个想法是登录这个应用程序,然后能够看到我的哪些 facebook 用户也在使用该应用程序及其功能。 最佳答案 是的。
我在连接或打印字符串时遇到了一个奇怪的问题。我有一个 char * ,可以将其设置为字符串文字的几个值之一。 char *myStrLiteral = NULL; ... if(blah) myS
对于以下数据 - let $x := "Yahooooo !!!! Select one number - " let $y := 1 2 3 4 5 6 7 我想得到
我正在看 UDEMY for perl 的培训视频,但是视频不清晰,看起来有错误。 培训展示了如何使用以下示例连接 2 个字符串: #!usr/bin/perl print $str = "Hi";
我是一名优秀的程序员,十分优秀!