Skip to content

#7 createCipheriv 里的 aes-256-ecb 加密使用注意事项 #7

@liuqipeng417

Description

@liuqipeng417

由于 nodejs 里的 crypto 里的各类加密方法是黑盒的,仅暴露了数个配置项,例如 createCipheriv

/**
algoritihm 即加密算法
key 即秘钥
iv 即初始化向量
**/
crypto.createCipheriv(algorithm, key, iv);

其实如果是用 nodejs 进行加解密是非常简单的,但这次是与客户端对接,node 加密,c++ 解密,两端的默认配置项都有参数的不一致,就需要详细的了解这里面加密算法的所有配置项。

注意:

1、如果用 createCipher 会发现 nodejs 生成的加密内容,大部分语言都无法解密,这是因为其他语言的库基本都是带 iv 的,不带 iv 的安全性比较低,容易被暴力破解。后续 createCipher 是会被 createCipheriv 给取代的,具体的参考 此处

2、秘钥的 bit 位数要与加密块长度一致,例如 aes-128-ecb,即需要使用 16 个字节的秘钥

aes 加密

相对于其他加密算法,aes 有非常多不同模式的加密

image

每个模式的 iv 不同,padding 不同,这两个就是造成与客户端对接的难点,官方文档里没有指出此方法默认的 iv 和 padding

padding

padding 是用来填充加密数据最后一块内容,使得变成一整块,对于加密解密需要使用同一的 padding。可是从上面的方法来看并没有自定义设置 padding 的选项,仅找到:

cipher.setAutoPadding([autoPadding])

当使用块加密算法时,Cipher类会自动添加padding到输入数据中,来适配相应块大小。可调用cipher.setAutoPadding(false)禁用默认padding。当autoPadding是false时,整个输入数据的长度必须是cipher块大小的倍数,否则cipher.final()将抛出一个错误。

这个方法一般用来保证输入内容的长度

aes-ecb 无需 iv

遇到的第一坑就是,无论我输入 iv 的长度为多少,都会被告知 invalid iv length

image

其实 ecb 模式下的加密,iv 就只能是空串,不能是其他的

ecb 的默认 padding

其次遇到的问题是,加密后端的内容默认会多一些(16)字节,这些字节其实就是 padding,但是 nodejs 文档里并没提到关于 aes-256-ecb 实现 padding 是多少。

后面经过多次尝试,发现默认 padding 为 PKCS_PADDING(PKCS5Padding)

后续查找了一些文档,发现各模式的 padding 选项:

image

可以发现如果某个块不满 16 字节,默认是会帮我们填充至 16 字节,如果恰好每个块都是 16 字节,则默认在末尾增加 16 字节 padding。

这幅图来自参考链接 2,其中文章里说:

node.js语言本身默认不补全填充量

根据测试,如今的 nodejs 默认是会填充 padding 的,也就是前面说的 setAutoPadding 默认为 true

参考

1、理解AES加密解密的使用方法
2、node.js AES/ECB/PKCS5Padding 与其他语言的加密解密通用

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions