4

我有一个 API 可以调用,我必须使用 RSA/ECB/PKCS1 填充和 AES/CBC/PKCS5PADDING 加密我的数据。

Sample Data: {"KEY":"VALUE"}

步骤1:

I have to generate a random number of 16 digit. eg: '1234567890123456'

第2步:

Do RSA/ECB/PKCS1Padding to random number and base64Encode the result. we get "encrypted_key"

步骤 3:

Concatenate random number & data:
DATA = 1234567890123456{"KEY":"VALUE"}

第4步:

Do AES/CBC/PKCS5Padding on DATA (from Step 3) using random number(1234567890123456) as KEY & Base64Encoded random number as IV. we get "ENCRYPTED_DATA"

因此,对于第 1 步,我使用的是JSEncryptjavascript 库。对于第 4 步,我正在使用CrytoJS.AES.encrypt()函数。我很确定我的 JSEncrypt 函数运行良好,因为客户端能够解密它,但客户端无法解密我的数据。我觉得我在使用CryptoJS.

有人可以正确指导我如何使用图书馆。

我正在做的是:

KEY =  '1234567890123456'
IV  = MTIzNDU2Nzg5MDEyMzQ1Ng==  (result of btoa('1234567890123456') )
DATA = "1234567890123456{"KEY":"VAL"}"

cryptedData = Crypto.AES.encrypt(DATA, KEY, {iv: IV, mode: CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7})

我被告知要PKCS5Padding在 AES/CBC 加密中使用(第 4 步),但似乎AES不支持PKCS5PaddingPKCS7Padding

我认为我将 K​​EY 和 IV 传递给CryptoJS.

任何帮助将不胜感激。

4

1 回答 1

2

首先让我们看看你为什么要做这个练习。RSA 旨在仅对有限数量的数据进行编码。所以我们使用“混合加密”,其中数据使用带有随机密钥的对称密码加密,而密钥本身使用 RSA 加密

加密适用于二进制数据,为了安全地传输二进制数据,数据被编码为可打印的形式(十六进制或base64)

Step.1:我必须生成一个16位的随机数

我们看到的是 16 位数字 0-9。那不是很安全。生成 16 位数字,您将得到 10 ^ 16 的密钥,大约等于 2 ^ 53(如果我做错了数学,请发表评论)。

您需要生成 16 个随机字节(数字 0-256 产生 2^128 键)。那是您的 DEK(数据加密密钥)。

您可以将 DEK 编码为可打印形式,在十六进制编码中它将有 32 个字符。

第2步:

好的,你现在得到加密的encoded_encryption_key

第 3 步、第 4 步

在这里你应该明白你在做什么。

  • 使用 DEK 加密数据(不是以二进制形式编码的随机数),您将获得 encrypted_data。您可以将结果编码为 encoded_encrypted_data
  • 连接加密的密钥和加密的数据。它。由您决定是在编码之前还是之后对其进行编码。我建议你用一些分隔符连接encoded_encryption_keyencoded_encrypted_data,因为如果RSA 密钥长度发生变化,encoded_encryption_key 的长度也会发生变化。确保与客户端讨论确切的预期格式。

笔记:

  • AES 和 CryptoJS 的 IV 需要 16 个字节长,我相信它需要进行十六进制编码,因此使用 btoa 可能不是最好的主意。我相信 CryptoJS 只是将值修剪为 16 个字节,但形式上它是不正确的。
    • CBC 密码需要某种完整性检查,我建议在结果中添加一些 HMAC 或签名(否则有人可能会在您无法检测到篡改的情况下更改密文)

但似乎 AES 不支持 PKCS5Padding 但 PKCS7Padding。

事实上,AES 支持 Pkcs7。Pkcs5 功能相同,但定义在 64 个块上。Java 中仍然使用该名称作为 DES 加密的遗产。

于 2019-04-11T11:08:05.927 回答