返回介绍

实战:加解密中的编码与字节序

发布于 2024-10-12 12:11:04 字数 1672 浏览 0 评论 0 收藏 0

在加解密场景中,通常会对 明文 加密得到 密文 ,对密文解密得到明文。比如对密码"123456"(明文)进行 对称加密 (如 SM4)得到"G7EeTPnuvSU41T68qsuc_g"(密文)。 明文和密文都是由可打印字符构成的文本 ,通常明文人类可直接阅读其含义(不考虑二次加密),密文需要解密后才能理解含义。

那么上述明文变成密文,期间经历了哪些编码过程呢?以加密为例:

  1. 将明文"123456"进行字符解码(如 UTF-8),得到 明文字节序列 0x31 32 33 34 35 36;
  2. 将明文字节序列输入 SM4 加密算法,输出 密文字节序列 0x1b b1 1e 4c f9 ee bd 25 38 d5 3e bc aa cb 9c fe;
  3. 将密文字节序列进行二进制编码(如 RawURLBase64),得到密文"G7EeTPnuvSU41T68qsuc_g";

同理,将"G7EeTPnuvSU41T68qsuc_g"解密成"123456"过程中,应与加密过程的编码方式对应:先进行 RawRULBase64 解码,再解密,最后再进行 UTF-8 编码。

加解密算法的输入输出都是字节序列,所以要将明文、密文与字节序列进行转换。有两点需要注意:

  1. 明文解码为明文字节序列,解码方式因场景而定 。对于多次加密场景(如对“G7EeTPnuvSU41T68qsuc_g”再次加密),明文是 Base64 编码得到的,建议采用一致的方式解码。虽然也可以直接进行 UTF-8 解码,但会使加解密流程设计变得复杂。
  2. 密文字节序列编码为密文,必须用二进制编码,不能用字符编码 。使用字符编码会产生乱码(意味着数据丢失,无法逆向解码出原始数据)。

合规要求,加解密场景中应使用 硬件加密机 。通常硬件加密机提供 基于 TCP 的字节流通信方式 ,比如约定每次通信数据中的前 2 字节为数据长度,后面的为真实数据。发送时,需要将真实数据长度转为 2 字节拼在前面,接收时,需要先读取前两字节得到真实数据长度 N,再读取 N 字节得到真实数据。其中 长度与字节序列的转换需要关注字节序:发送方和接收方的字节序处理保持一致 即可,比如全用大端。下面给出了数据发送的示例代码:

func (m *EncryptMachine) sendData(conn net.Conn, data []byte) error {
    // add length
    newData := m.addLength(data)
    // send new data
    return util.SocketWriteData(conn, newData)
}

func (m *EncryptMachine) addLength(data []byte) []byte {
    lengthBytes := make([]byte, 2)
    binary.BigEndian.PutUint16(lengthBytes, uint16(len(data)))
    return append(lengthBytes, data...)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文