使用 Java 加密 JSON 负载

问题描述 投票:0回答:1

我正在尝试测试此 webhook 有效负载是否已正确加密。这是我用来加密有效负载的 java 代码。

def byte[] encrypted
        try {

            String jsonMessage = new Gson().toJson( responseObject )

            System.out.println("JPM_B2B Salesforce: ${jsonMessage}")

            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] derivedKey = digest.digest("SQz36N5r8bSzcSMnIeQl9MmxybFLGWRTq3WfCvL+S40=".getBytes(StandardCharsets.UTF_8));

            SecretKeySpec secretKey = new SecretKeySpec(derivedKey, "AES");
            byte[] iv = new byte[16];
            IvParameterSpec ivSpec = new IvParameterSpec(iv);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);

            encrypted = cipher.doFinal(jsonMessage?.getBytes(StandardCharsets.UTF_8));
            System.out.println("JPM_B2B Salesforce: Encrypted ${encrypted}")

        }catch(Exception e){
            System.out.println("JPM_B2B Salesforce: Unable to encrypt webhook data")
            responseObject = [success:false, msg:"Error: ${e.getMessage()}"]
            e.printStackTrace()
        }

        response.setContentType("application/json")

        if(encrypted) {
            out.write( Base64.getEncoder().encodeToString(encrypted) )
        }else {
            out.write( new Gson().toJson( responseObject ) )
        }

这是我收到的输出之一:

w9oTb0Mk8R0sM1YILhb/kWmtyZNWM6jSPHgB53A5BTVXDUA23MOIu4SivwLczOaU22ewmFZ+giRcvM9B3boQD/hAhLDZbANvrYDIfTQFy+kgYSLoBwI295QMa9XRCkL3Ua+z9kvMl6qsDVxm6wsKPSlVe8APgTg8rMuABPZIIVWJl+ACPqiXGWZFq+f7sdCfMyswtqLyfmksA9tQW0fuivdvNWyzbpa5QnURWGPxVojEao69Q3BhS2PypUOYSgmPT92rhYhb9fwVsdsQsXLcSB543j+XVSyWqOl5najPVylTVVjN1tB7jLdOgV9fcfaKzktnF7DOCB6QX68hqap0XT7X3r410fUOp5I0IO23Za1YCl5H45oirpDfdWxf4CK138X16TuGI8Gjxb8BQ1JNo5Rhxk606XrPwSppdL63kr38SejnGked5iMW+qZO1tbqnEHlrb8K6MFgEY8Od2vBS4u0BFfY0n+6G0/ldqMFyA3qK/mZ7gPXWdjzd0QKVNrir1r5D8Ks1gNvVey5Fjk1cCmoMIjaRJZZh+1IDqcEFCCgmueH1hvPVVWIVyHXsr7dK92WyZsUqxw0Va4//QwRDJMJ0kxVKqDVczFVgkAHNdy3PTQb0VsLauZiLYV6HntFe/+39t66id6sDA3Dl8EksK2j/x0CD7SHldRZ5GS7gnr7xwoJNspq+ApCBQJuTfoMwtCZYqWlesmIwPotnwnxUw==

好的。现在通过解密来测试。我创建了一个文件,然后在计算机上使用这个小 bash 脚本来查看它是否有效:

#!/bin/bash

set -e  # Exit on any error

echo "Step 1: Decoding base64 files"
base64 --decode -i webhookEnc.base64 > jpmWebhook.bin
base64 --decode -i sfKey.base64 > sfKey.bin

echo "Step 2: Displaying first few bytes of the key"
xxd -l 32 sfKey.bin

echo "Step 3: Deriving the key using SHA-256"
openssl dgst -sha256 -binary -out derived_key.bin sfKey.bin

echo "Step 4: Displaying first few bytes of the derived key"
xxd -l 32 derived_key.bin

echo "Step 5: Creating a zero IV"
dd if=/dev/zero of=zero_iv.bin bs=1 count=16 2>/dev/null

echo "Step 6: Attempting decryption"
if openssl enc -aes-256-cbc -d -in jpmWebhook.bin -out decryptedWebhook.txt -K $(xxd -p -c 32 derived_key.bin) -iv $(xxd -p -c 32 zero_iv.bin) -nosalt; then
    echo "Decryption successful. Output in decryptedWebhook.txt"
    echo "First few lines of decrypted content:"
    head -n 5 decryptedWebhook.txt
else
    echo "Decryption failed. Error message:"
    openssl enc -aes-256-cbc -d -in encrypted_data.bin -out decryptedWebhook.txt \
    -K $(xxd -p -c 32 derived_key.bin) \
    -iv $(xxd -p -c 32 zero_iv.bin) \
    -nosalt 2>&1
fi

我不断收到“尝试解密 解密错误 4047D4BE607F0000:错误:1C800064:提供程序例程:ossl_cipher_unpadblock:解密错误:../providers/implementations/ciphers/ciphercommon_block.c:124:“

我想我可能错过了一个步骤或其他东西,但我不知道它是什么!

java openssl
1个回答
0
投票

我不确定从 Java 代码派生的密钥与从 Bash 脚本派生的密钥是否匹配。在 Java 代码中,您使用 Base64 编码的字符串

SQz36N5r8bSzcSMnIeQl9MmxybFLGWRTq3WfCvL+S40=
,并使用
SHA-256
进行散列来派生 AES 密钥,但在 Bash 脚本中,您从
sfKey.bin
派生密钥,这可能不是与 Java 代码中使用的 Base64 编码字符串相同。您可能想直接在脚本中对其进行解码(而不是从文件中读取)
echo "SQz36N5r8bSzcSMnIeQl9MmxybFLGWRTq3WfCvL+S40=" | base64 --decode > sfKey.bin

Java 加密使用

AES/CBC/PKCS5Padding
,这意味着对加密数据应用填充。 OpenSSL 自动使用
-aes-256-cbc
处理填充,所以我希望格式在这里正确对齐。

您提到Java和OpenSSL使用相同的IV(初始化向量)。在您的 Java 代码中,您使用的是清零 IV(新字节 [16]),但在您的 Bash 脚本中它创建了

zero_iv.bin
,所以我希望它匹配相同的值

最后要检查/验证的一件事是,当您解码 Base64 编码的有效负载(在 bash 脚本中)时,不会引入额外的数据或无效字符。有时,Base64 编码字符串中的空格可能会导致问题。您可以使用 xxd 或 hexdump 检查原始二进制数据并将其与 Java 输出进行比较。您还可以尝试将 -debug 添加到 OpenSSL 命令中,以在解密过程中获取更详细的信息,如

openssl enc -aes-256-cbc -d -in jpmWebhook.bin -out decryptedWebhook.txt -K $(xxd -p -c 32 derived_key.bin) -iv $(xxd -p -c 32 zero_iv.bin) -nosalt -debug

© www.soinside.com 2019 - 2024. All rights reserved.