Crypto(加解密算法)
# 简介
crypto 是加密模块, 提供了一套常见的加密算法和校验算法. 可以涵盖信息的加解密传输, 登陆认证, 信息签名等大多数使用场景.主要包含了 rsa, aes, crc, xxtea, sha256, sha1, md5, base64. 这几种算法.
# 算法说明
## RSA
被研究得最广泛的公钥算法,从提出到现在已近三十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。
```lua
local publicKey = io.readFile("/lua/public.key")
local publicKeyLen = 2048
local privateKey = io.readFile("/lua/private.key")
local privateKeyLen = 2048
-- 公钥加密
local encryptStr = crypto.rsa_encrypt("PUBLIC_KEY", publicKey, publicKeyLen, "PUBLIC_CRYPT", str)
log.info("rsa encrypt", encryptStr:toHex())
-- 私钥解密
local decryptStr = crypto.rsa_decrypt("PRIVATE_KEY", privateKey, privateKeyLen, "PRIVATE_CRYPT", encryptStr)
log.info("rsa decrypt", decryptStr)
-- 私钥签名
local signStr = crypto.rsa_sha256_sign("PRIVATE_KEY", privateKey, privateKeyLen, "PRIVATE_CRYPT", str)
log.info("rsa sign", signStr:toHex())
-- 公钥验签
local verifyResult = crypto.rsa_sha256_verify("PUBLIC_KEY", publicKey, publicKeyLen, "PUBLIC_CRYPT", signStr, str)
log.info("rsa verify", verifyResult)
```
## AES
常见对称加密算法, 因为易于实现, 占用硬件资源较少, 所以广泛应用于嵌入式领域, 作为新一代的加密标准,具有安全性高、性能高、效率高、使用方便、灵活性高等优点,能够很快的完成加解密运算.
```lua
local key = "1234567890123456"
-- 加密模式:ECB, 填充方式:ZeroPadding, 密钥:1234567890123456, 密钥长度:128 bit
local encodeStr = crypto.aes_encrypt("ECB", "ZERO", str, key)
log.info("aes encode", encodeStr:toHex())
log.info("aes decode", crypto.aes_decrypt("ECB", "ZERO", encodeStr, key))
```
## XXTEA
对称加密算法, 算法的结构非常简单,只需要执行加法、异或和寄存的硬件即可,且软件实现的代码非常短小,具有可移植性。
```lua
local key = "12345";
local encodeStr = crypto.xxtea_encrypt(str, key)
log.info("xxtea encode", encodeStr:toHex())
log.info("xxtea decode", crypto.xxtea_decrypt(encodeStr, key))
```
## CRC
是一种常见的校验算法,主要用来检测或校验数据传输或者保存后可能出现的错误。它是利用除法及余数的原理来作错误侦测的。
```lua
log.info("crc modebus encode", string.format("%04X", crypto.crc16("MODBUS", str)))
```
## MD5
MD5信息摘要算法,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致
```lua
--计算字符串的md5值
local originStr = "sdfdsfdsfdsffdsfdsfsdfs1234"
log.info("testCrypto.md5",crypto.md5(originStr,slen(originStr)))
-- crypto.md5,第一个参数为文件路径,第二个参数必须是"file"
log.info("testCrypto.sys.lua md5",crypto.md5("/lua/sys.lua","file"))
```
## SHA256
安全散列算法,生成一个固定长度的 hash 值, 主要也是用来校验.
```lua
local originStr = "sdfdsfdsfdsffdsfdsfsdfs1234"
log.info("testCrypto.sha1",crypto.sha256(originStr,slen(originStr)))
```
## BASE64
属于一种编码方式, 可以将一个 8bit 的数据转化为可见字符. 之所以称为Base64,是因为其使用64个字符来对任意数据进行编码,同理有Base32、Base16编码
```lua
local originStr = "123456crypto.base64_encodemodule(...,package.seeall)sys.timerStart(test,5000)jdklasdjklaskdjklsa"
local encodeStr = crypto.base64_encode(originStr,slen(originStr))
log.info("testCrypto.base64_encode",encodeStr)
log.info("testCrypto.base64_decode",crypto.basehttps://doc.openluat.com/wiki/6?wiki_page_id=1766
```
# API说明
> 详细的API介绍见 [crypto API章节](https://doc.openluat.com/wiki/21?wiki_page_id=2245)
# 应用场景
在某些通信场景数据只能透传, 所以用户需要自己构建加密方式, 或者用户希望提高保密性, 需要已经加密的信道(这里的信道主要指通信中的通道)上进行二次加密. 上述算法就是为了满足这些需求出现的. 在数据传输上, 非对称加密相对于来说较为安全, 因为这样的数据可以在非安全的信道进行传输, 即使模块端源代码泄漏, 也可以保证数据安全传输, 只要保证私钥不泄漏即可, 但是非对称加密相对于对称加密运行速度要慢上好几个数量级, 而且内存占用较大, 所以通常用非对称加密传递一个对称加密的密钥, 然后用对称加密进行通信, 所以一个典型的加密通信的场景如下:
1. 首先用公钥加密模块的信息发送登陆认证报文, 例如 imie, iccid 等, 可以添加时间戳, 或者随机数, 这样可以保证每次发送的密文都是不相同的, 可以防止窃听者用固定报文登陆.
2. 云服务器端获取到模块发送的登陆信息之后用私钥解密, 然后生成一个用于对称加密的密钥, 用非对称加密的私钥加密这些信息之后发送给模块.
3. 模块用公钥解密信息之后可以获取对称加密所需的密钥
4. 随后, 双方的通信方式全部采用非对称加密.
也就是说, 模块端只存储非对称加密的公钥, 对称加密所需的密钥是在服务端动态生成, 通过私钥加密下发, 即使源码和通信协议泄漏, 也只是泄漏公钥, 报文传输的内容依然是安全的.

# 示例
> 详细的 API demo见[Crypto demo章节](https://doc.openluat.com/wiki/21?wiki_page_id=2170)
# 常见问题
1.如何生成 RSA 加密所需公私密钥
在线搜索 RSA 加密可以找到各种网站进行签名或者验证运算, 也可以通过一些工具进行验证计算
[RSATool.zip](https://cdn.openluat-luatcommunity.openluat.com/attachment/20210506203240758_RSATool.zip)
## 相关资料
[Crypto API说明](https://doc.openluat.com/wiki/21?wiki_page_id=2245)
[Crypto demo讲解](https://doc.openluat.com/wiki/21?wiki_page_id=2170)