【问题标题】:RSA AES decryption with junk characters带有垃圾字符的 RSA AES 解密
【发布时间】:2015-03-23 23:34:02
【问题描述】:

我正在尝试使用 AES 和 RSA 解密 saml 响应,并且可以正确解密 saml 断言。但是,解密后的文本被嵌入到一些垃圾字符中,导致解析异常。

下面是我的代码

InputStream privateKeyFileInputStream = Check.class.getClassLoader().getResourceAsStream("rsa_privatekey.key"); 
rsaPrivateKey = new byte[privateKeyFileInputStream.available()];
privateKeyFileInputStream.read(rsaPrivateKey);

PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
PrivateKey privKey = keyFactory.generatePrivate(privateKeySpec);

Cipher cipher1 = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");
cipher1.init(Cipher.DECRYPT_MODE, privKey);

byte[] encryptedMessage = Base64.decodeBase64(aesPrivateKeyEnc.getBytes());
aesPrivateKey = cipher1.doFinal(encryptedMessage);

IvParameterSpec ivSpec = new IvParameterSpec(new byte[16]);
SecretKeySpec key = new SecretKeySpec(aesPrivateKey, "AES");
Cipher cipher2 = Cipher.getInstance("AES/CBC/NoPadding", "BC");
cipher2.init(Cipher.DECRYPT_MODE, key, ivSpec);

byte[] cipherTextBytes = Base64.decodeBase64(cipherText);        
byte[] decryptedMessage = cipher2.doFinal(cipherTextBytes);

String message = new String(decryptedMessage, "UTF8");

现在,消息有

R����=2�W���?<saml:Assertion ...... </saml:Assertion>��fE]����

【问题讨论】:

  • 您没有保留 unicode 字符,或者您在打印消息的任何地方都不支持显示它们。控制台默认没有。
  • 如何保存?解密的文本(在垃圾字符之间)没有任何问题。
  • “我如何保存?” - 到处使用 UTF-8 进行系统互连。它最具互操作性。您可能仍需要转换为本地编码(如 Windows 上的 UTF-16)。

标签: java encryption aes rsa saml


【解决方案1】:

您的 IV 值似乎以密文为前缀。您应该将密文的前 16 个字节用于cipher2,而不是零 IV。不要忘记将它们排除在加密之外。这解释了开头的垃圾。

您的cipher2 似乎也应该配置为填充。这可能是 PKCS#7 填充。请尝试"AES/CBC/PKCS5Padding" 而不是"/NoPadding"。如果这不起作用,您需要使用纯文本 十六进制 更新您的问题,以便我们确定使用哪个填充。这应该可以解释最后的垃圾。

请注意 Java 中的 "PKCS5Padding" does perform PKCS#7 padding

【讨论】:

  • 抱歉,我没有收到“您应该使用密文的前 16 个字节来代替零 IV 来代替 cipher2”。我怎样才能明确排除?文末的垃圾怎么办?启用填充(PKCS5Padding)抛出“javax.crypto.BadPaddingException:pad block损坏”。
  • IvParameterSpec ivSpec = new IvParameterSpec(new byte[16]); 使用cipherTextBytes 的前16 个字节。可以使用Arrays.copyOfRange方法将字节数组一分为二。
  • cipherTextBytes 已在代码末尾和 ivSpec 之后派生。您指的是其他文本吗?
  • 不,我不是。我认为用cipherTextBytes 的前16 个字节替换new byte[16] 没有任何问题。您尝试过吗?
  • 您仍然需要将密文拆分一分为二(在检索到 IV 字节后跳过或删除它们)。您能否对解密后的明文结果进行十六进制或 base 64 编码并在此处发布?随机数据如果直接当作字符串处理会丢失信息,所以它不会给我们任何信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-25
相关资源
最近更新 更多