【问题标题】:First 16 Characters of decrypted string are garbage解密字符串的前 16 个字符是垃圾
【发布时间】:2021-04-28 01:12:19
【问题描述】:

我有一个场景,数据从 API 加密,然后在打字稿中解密。我在 typescript 中使用 cryptoJS 进行解密。以下是我的解密代码:

decrypt(source: string, iv: string): string {
var key = environment.config.KEY_PAYMENT.substring(0, 32);
const keyValue = CryptoJS.enc.Utf8.parse(key);
const ivValue = CryptoJS.enc.Utf8.parse(iv);
const plainText = CryptoJS.AES.decrypt(source, keyValue, {
  keySize: 16,
  iv: ivValue,
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.Pkcs7
});
return CryptoJS.enc.Latin1.stringify(plainText);

} 提供了 IV 和键值。我有一个 Java 示例代码,用于解密按预期工作的移动应用程序。代码示例在这里:

fun decrypt(
    source: ByteArray,
    key: String,
    iv: ByteArray
  ): ByteArray {
    val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
    cipher.init(Cipher.DECRYPT_MODE, makeKey(key), makeIv(iv))
    return cipher.doFinal(source)
  }

  private fun makeIv(iv: ByteArray): AlgorithmParameterSpec {
    return IvParameterSpec(iv)
  }

  private fun makeKey(baseKey: String): Key? {
    return try {
      val key = baseKey.substring(0, 32)
          .toByteArray(charset("UTF-8"))
      SecretKeySpec(key, "AES")
    } catch (e: UnsupportedEncodingException) {
      null
    }
  }

样本输出:

ªîto7“ßH«3©@V¨sr","paymentType":"credit_card",...

前 16 个字符是垃圾,字符串的其余部分已成功解密。我被困在这里了。

【问题讨论】:

  • IV 不应使用const ivValue = CryptoJS.enc.Utf8.parse(iv); 传递。 IV 是二进制的,它不包含可打印的字符。如果需要字符串,请使用十六进制或 base 64 编码/解码。
  • @MaartenBodewes 我正在使用 atob() 但它仍然无法正常工作。然后我尝试了 CryptoJS.enc.Base64.parse(iv),它成功了。
  • 在堆栈交换结束我的问题后,能够在此评论前一天解决问题。你已经指出了正确的方向。谢谢。
  • 完美,很高兴你解决了 :)

标签: javascript angular typescript encryption aes


【解决方案1】:

“前 16 个字符错误;其他一切看起来都不错”通常意味着您的 IV 错误。

您提供的代码中的所有内容看起来都是合法的;我怀疑要解密的调用者没有传递正确的 IV 值。

【讨论】:

  • IV 的解码不合法。
  • 在堆栈交换结束我的问题后,能够在此评论前一天解决问题。不过,您已经指出了正确的方向。谢谢。
【解决方案2】:

这对我有用:

  decrypt(source: string, iv: string) {
    debugger;
    var key = environment.config.KEY_PAYMENT.substring(0, 32);
    const keyValue = CryptoJS.enc.Utf8.parse(key);
    const ivVal = CryptoJS.enc.Base64.parse(iv);//This Line
    const plainText = CryptoJS.AES.decrypt(source, keyValue, { iv: ivVal });
    return CryptoJS.enc.Latin1.stringify(plainText);
  }

crypto JS 有它自己的 base64 编码函数,可以返回正确的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多