解密无法获取全部键值对,如何实现完整解密并还原原始Payload?
问题分析与解决方案
核心问题
- 密钥处理错误:直接对字符串
"secret"执行Base64解码不合法——"secret"并非有效的Base64编码内容,会导致生成的密钥长度不符合AES算法要求(必须为16/24/32字节),最终引发解密乱码。 - 解密对象错误:当前代码误将明文的
teacher.profileJSON对象当作加密字符串解密,逻辑完全错误。正确逻辑应为:原始加密Payload中teacher.profile是Base64编码的密文,你提供的JSON Payload是解密后的目标结构。 - 数据缺失:代码仅处理了teacher部分,未保留student数据,导致最终输出缺失该内容。
修正后的代码
假设原始加密Payload结构为:student是明文,teacher.profile是Base64加密字符串,teacher.iv是Base64编码的初始向量。修正后的代码会保留student数据,正确解密teacher.profile,并重组为与目标Payload一致的完整结构:
import javax.crypto.spec.SecretKeySpec; import java.io.FileReader; import java.util.Base64; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; public class TestClass { public static void main(String[] args) throws Exception { // 注意:此处secret需为Base64编码后的合法AES密钥(长度16/24/32字节) String secretBase64 = "c2VjcmV0X3NlY3JldA=="; // 示例:Base64编码的"secret_secret"(16字节) JSONParser parser = new JSONParser(); Object object = parser.parse(new FileReader("src/main/resources/test_encrypted.json")); JSONObject jsonObject = (JSONObject) object; // 保留明文的student数据 JSONObject student = (JSONObject) jsonObject.get("student"); // 处理teacher的加密部分 JSONObject teacherEncrypted = (JSONObject) jsonObject.get("teacher"); String encryptedProfile = (String) teacherEncrypted.get("profile"); String ivBase64 = (String) teacherEncrypted.get("iv"); byte[] key = Base64.getDecoder().decode(secretBase64); byte[] iv = Base64.getDecoder().decode(ivBase64); // 解密profile并转为JSON对象 String decryptedProfileStr = decryption(encryptedProfile, key, iv); JSONParser profileParser = new JSONParser(); JSONObject decryptedProfile = (JSONObject) profileParser.parse(decryptedProfileStr); // 重组teacher对象 JSONObject teacher = new JSONObject(); teacher.put("profile", decryptedProfile); teacher.put("iv", ivBase64); // 若无需保留iv可删除此行 // 重组完整Payload JSONObject finalPayload = new JSONObject(); finalPayload.put("student", student); finalPayload.put("teacher", teacher); System.out.println("解密后完整Payload:"); System.out.println(finalPayload.toJSONString()); } public static String decryption(String cipherText, byte[] myKey, byte[] IV) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKeySpec keySpec = new SecretKeySpec(myKey, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(IV); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); byte[] decryptedText = cipher.doFinal(Base64.getDecoder().decode(cipherText)); return new String(decryptedText); } }
关键说明
- 密钥规范:确保
secretBase64是Base64编码后的合法AES密钥,长度必须为16(AES-128)、24(AES-192)或32(AES-256)字节。 - 原始加密Payload示例:你的加密输入文件(
test_encrypted.json)需符合如下结构:
{ "student": { "firstname": "Joan", "lastname": "lastname" }, "teacher": { "profile": "加密后的Base64字符串", "iv": "ivvvv" } }
- 完整输出:修正后的代码会同时保留student数据与解密后的teacher数据,输出结构与你提供的目标Payload完全一致。
内容的提问来源于stack exchange,提问作者jhon
相关产品推荐
相关产品推荐

