物联网安全基础知识:加密技术的使用
在工业、医疗、运输及其他关键应用中,对物联网应用的依赖程度迅速增加,这极大地改变了安全格局。以往,企业应用普遍拥有随时可用的资源来处理安全算法,但如今企业级物联网应用却饱受威胁日益增多之苦,且其攻击目标是不断扩大的资源受限型物联网设备网络。企业在急于迎接快速涌现的物联网机遇时,部署的物联网设备在功能上往往无法支持基本的安全措施,因此难以保护存储的数据,且无法保证在易受攻击的网络上进行数据和命令交换。
当然,开发人员需要做到什么程度才能确保设计安全取决于多个因素。每个应用都面临着各自的威胁,因而需要对这些威胁带来的风险进行适当的评估。由于互连设备面临的威胁数量不同以往,任何物联网设备都至少需要一些最低限度的安全措施。
在一些人看来,为简单的物联网设备实施强大的安全措施似乎是过度设计,但即使是简单的温度传感器,如果缺乏足够的保护,也会成为黑客入侵企业网络的切入点[1]。其实,正因为物联网应用提供了普遍连接性,而这些应用却基于资源受限的设备,才导致物联网安全持续面临挑战。事实上,即使物联网设备设计提供足够的资源在软件中执行加密算法,但只要这些算法在实现过程中存在细微错误,应用仍然可能易受攻击。
本文介绍了加密算法的基本类别,并探讨了它们在安全方面的作用。然后,本文将向开发人员展示如何利用 Maxim Integrated、Microchip Technology 和 Texas Instruments 提供的旨在加速这些算法的处理器和专用器件,以在简化实现的同时增强安全性的不同方面。
各种类型的加密算法及其作用
加密算法可分为三大类,涉及机密性、身份验证(验证消息来源)、不可抵赖性(证明发送方创建了加密或签名的消息)和完整性等基本安全原则:
对称密钥算法,即算法或加密法使用相同的密钥,将人类可读的(明文)消息加密为受保护的版本(密文),之后再将密文解密为明文。对称密钥加密法通常用于确保机密性。常见的对称加密算法包括:
Triple DES(一种数据加密标准),又称为 3DES,或由美国国家标准与技术研究院 (NIST) 正式命名的三重数据加密算法 (TDEA)。
高级加密标准 (AES)[2] 算法,例如使用 256 位密钥的 AES-256。
非对称密钥算法,即加密法使用一组成对的私钥和公钥对消息进行加密和解密,通常作为密钥协议和数字签名安全扩展协议的一部分。非对称加密法通常用于确保机密性、身份验证或不可抵赖性。公钥加密算法包括:
椭圆曲线 Diffie-Hellman (ECDH)[5] 密钥交换
椭圆曲线数字签名算法 (ECDSA)[6]
Rivest-Shamir-Adleman (RSA)[4] 算法
联邦信息处理标准 (FIPS) 数字签名算法 (DSA)
互联网工程任务组 (IETF) Diffie-Hellman (DH)[3] 密钥交换
使用有限域加密 (FFC) 的算法,包括:
使用整数分解加密 (IFC) 的算法,包括:
使用椭圆曲线加密 (ECC) 的算法,包括:
哈希算法,此算法将原始消息缩减为一个很短且长度固定的唯一值,常称为哈希值、摘要或签名。这种单向转换函数在验证消息是否遭到窜改(完整性)方面扮演重要角色,可应用于涉及消息验证码 (MAC)、密钥哈希消息验证码 (HMAC) 或密钥派生函数 (KDF) 等的多种协议。加密哈希算法包括:
消息摘要 5 (MD5)
安全哈希算法 (SHA)[7],例如将消息转换成 256 位哈希值的 SHA-256。
与所有有效的加密算法一样,上述算法的设计也需遵循多个关键要求,本文碍于篇幅,无法详细列出。但从广义角度来看,基于密钥的算法需要生成的密文几乎无法在无密钥的情况下解密(至少从经济角度来说不可行)。哈希算法必须快速生成哈希值:将相同的输入消息转换成相同的哈希值,但对于哪怕只是有细微变化的输入消息,也要生成截然不同的哈希值;并且,绝不会将两条不同消息转换成相同的哈希值,也不会因给定了特定的哈希值而生成原始消息。
尽管这些算法及其他加密算法在细节上有极大差异,但都仰赖一系列专门设计的低级操作、转换和其他数学运算,以便达成整体目标。例如,AES 加密法使用一系列“回合”将明文转换为密文,每个“回合”都会由用户原始密钥产生唯一的“回合密钥”,并将其与原矩阵合并(清单 1)。
Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)])
begin
byte state[4,Nb]
state = in
AddRoundKey(state, w[0, Nb-1])
for round = 1 step 1 to Nr–1
SubBytes(state)
ShiftRows(state)
MixColumns(state)
AddRoundKey(state, w[round*Nb, (round+1)*Nb-1])
end for
SubBytes(state)
ShiftRows(state)
AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
out = state
end
清单 1:这段伪代码说明了消息加密中涉及的操作序列,此序列使用一组由发送方私钥派生的值 (w),将明文 (in) 转换为密文 (out)。(代码来源:NIST)
在一个回合中,SubBytes() 转换使用替换表 (S-box) 替换每个字节,替换表本身也是一系列转换的结果(图 1)。
在序列的下一步中,ShiftRows() 转换将后三行中的字节移位,且每行移动不同的字节数(图 2)。
在序列的最后步骤中,MixColumns() 对每一列进行转换,用多项式的结果替换列中的每个字节;然后 AddRoundKey() 使用专为此目的创建的回合密钥,与各混合列中的字节进行按位异或 (XOR) 运算以转换结果。
回合总数因密钥大小而异。AES-128 使用 128 位密钥,需要 10 个回合,而 AES-192(密钥大小为 192 位)及 AES-256(256 位)分别需要 12 和 14 个回合。解密遵循相同的模式,只是反向执行各过程步骤及其各自的转换。
用于密钥交换的 ECDH 和用于数字签名的 ECDSA 等最新加密法依赖于更复杂的数学运算,例如由以下公式广泛定义的椭圆曲线代数结构:
通过慎重选择曲线参数 a 和 b 并使用其他约束条件,该曲线将显示出有用的加密属性(同样,本文无法详述)。虽然概念简单,但特定的参数组合至关重要:曲线参数选择不当会导致算法仍然无法抵御复杂的攻击。为了帮助消除这种可能性,NIST 提供了一组具有强鲁棒性的标准加密曲线,包括 P-192、P-224、P-256 和鲁棒性更强的其他曲线。曲线名称与曲线的底层素域中元素的素数 p 的位长相对应。
开发人员可使用这些属性结合 ECDSA,利用确定的曲线对部分消息进行签名,并将公钥和签名(一对标示为 r 和 s 的数字)提供给接收方。实际的签名过程包含以下步骤:
最终结果可以互换,用于验证消息、确认消息完整性,并确保不可抵赖性。
如何实现加密算法
Maxim Integrated 的 MAX32631 32 位微控制器,支持 AES 和 DSA 加密 Maxim Integrated 的 MAX32520 32 位 MCU,支持 AES、SHA 和 ECDSA 算法 Microchip Technology 的 PIC 24F XLP 16 位微控制器系列,其中 PIC24FJ256GA406 等器件支持 AES 和 3DES 加密 Microchip Technology 的 32 位 PIC 32MZ MCU 和 32 位 SAM9X60 MPU 系列,其中 PIC32MZ2048EFM144 和 SAM9X60T 等器件支持 AES 和 3DES 加密,以及 SHA 和 HMAC 哈希函数 Texas Instruments 的 SimpleLink MCU 系列,如 CC1312R 和 CC2652R 无线 MCU,支持 AES、ECDH 和 ECDSA 加密,以及 SHA 哈希函数
int AES128_ECB_enc(int asynchronous)
{
printf( asynchronous ? 'Test Cipher Async\n' : 'Test Cipher Sync\n');
char *_key = '797f8b3d176dac5b7e34a2d539c4ef36';
char key[MXC_AES_KEY_128_LEN];
ascii_to_byte(_key, key, MXC_AES_KEY_128_LEN);
const char *iv_src = '';
char iv_dst[16];
ascii_to_byte(iv_src, iv_dst, 16);
char *_pt= '00000000000000000000000000000000';
char pt[MXC_AES_DATA_LEN];
ascii_to_byte(_pt, pt, MXC_AES_DATA_LEN);
mxc_ctb_cipher_req_t cipher_req = {
(uint8_t*)pt,
MXC_AES_DATA_LEN,
(uint8_t*)iv_src,
(uint8_t*)result,
&Test_Callback };
// Reset crypto block
MXC_CTB_Init(MXC_CTB_FEATURE_CIPHER | MXC_CTB_FEATURE_DMA);
MXC_CTB_IntEnable(asynchronous);
MXC_CTB_Cipher_SetMode(MXC_CTB_MODE_ECB);
MXC_CTB_Cipher_SetCipher(MXC_CTB_CIPHER_AES128);
MXC_CTB_Cipher_SetKeySource(MXC_CTB_CIPHER_KEY_SOFTWARE);
// Load key into cipher key register
MXC_CTB_Cipher_SetKey((uint8_t *)key, MXC_AES_KEY_128_LEN);
if (asynchronous){
wait = 1;
MXC_CTB_Cipher_EncryptAsync(&cipher_req);
while( wait );
} else {
MXC_CTB_Cipher_Encrypt(&cipher_req);
}
const char *_expected = '322FD6E503395CDB89A77AC53D2B954F';
char expected[MXC_AES_DATA_LEN];
ascii_to_byte(_expected, expected, MXC_AES_DATA_LEN);
return AES_check(result, expected, MXC_AES_DATA_LEN);
}
int AES128_ECB_dec(int asynchronous)
{
printf( asynchronous ? 'Test Cipher Async\n' : 'Test Cipher Sync\n');
char *_key = '797f8b3d176dac5b7e34a2d539c4ef36';
char key[MXC_AES_KEY_128_LEN];
ascii_to_byte(_key, key, MXC_AES_KEY_128_LEN);
const char *iv_src = '';
char iv_dst[16];
ascii_to_byte(iv_src, iv_dst, 16);
char *_pt= '322FD6E503395CDB89A77AC53D2B954F';
char pt[MXC_AES_DATA_LEN];
ascii_to_byte(_pt, pt, MXC_AES_DATA_LEN);
mxc_ctb_cipher_req_t cipher_req = {
(uint8_t*)pt,
MXC_AES_DATA_LEN,
(uint8_t*)iv_src,
(uint8_t*)result,
&Test_Callback };
// Reset crypto block
MXC_CTB_Init(MXC_CTB_FEATURE_CIPHER | MXC_CTB_FEATURE_DMA);
MXC_CTB_IntEnable(asynchronous);
MXC_CTB_Cipher_SetMode(MXC_CTB_MODE_ECB);
MXC_CTB_Cipher_SetCipher(MXC_CTB_CIPHER_AES128);
MXC_CTB_Cipher_SetKeySource(MXC_CTB_CIPHER_KEY_SOFTWARE);
// Load key into cipher key register
MXC_CTB_Cipher_SetKey((uint8_t *)key, MXC_AES_KEY_128_LEN);
if (asynchronous){
wait = 1;
MXC_CTB_Cipher_DecryptAsync(&cipher_req);
while( wait );
} else {
MXC_CTB_Cipher_Decrypt(&cipher_req);
}
const char *_expected = '00000000000000000000000000000000';
char expected[MXC_AES_DATA_LEN];
ascii_to_byte(_expected, expected, MXC_AES_DATA_LEN);
return AES_check(result, expected, MXC_AES_DATA_LEN);
}
身份验证协议
密钥构建:RSA、DH、ECDH 身份验证:RSA、DSA、ECDSA 加密法:3DES、AES 消息验证:SHA