You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaCard AES加密与Javax AES解密结果不一致问题咨询

Troubleshooting AES-CBC-NoPad Mismatch Between JavaCard and Javax Crypto

Let’s walk through the most likely causes of your encryption/decryption mismatch, along with actionable checks and fixes:

1. Session Key Length Mismatch (High Probability)

Looking at your JavaCard code, you’re generating a 32-byte KEY_SESSION but initializing an AES-128 key (KeyBuilder.LENGTH_AES_128). When you call sessionKeySP.setKey(KEY_SESSION, (short) 0);, JavaCard automatically takes only the first 16 bytes of KEY_SESSION as the AES-128 key.

If your Javax code uses the full 32 bytes of the RSA-decrypted KEY_SESSION as the AES key, this will immediately break decryption.

Fix:

  • In your Javax code, after decrypting the RSA-encrypted session key, extract only the first 16 bytes to use as the AES-128 key.
  • Verify this by logging the first 16 bytes of KEY_SESSION in JavaCard (if possible) and comparing them to the first 16 bytes of the RSA-decrypted key in Javax.

2. IV Inconsistency

Your JavaCard code initializes AES-CBC with a 16-byte all-zero IV:

cipherAES.init(sessionKeySP, Cipher.MODE_ENCRYPT, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, (short) 0, (short) 16);

For CBC mode, the IV used during decryption must exactly match the IV used during encryption.

Check:

  • Ensure your Javax code uses the same all-zero IV when initializing the decrypt cipher:
    IvParameterSpec ivSpec = new IvParameterSpec(new byte[16]);
    Cipher decryptCipher = Cipher.getInstance("AES/CBC/NoPadding");
    decryptCipher.init(Cipher.DECRYPT_MODE, aesKey, ivSpec);
    
  • Double-check that no code is accidentally modifying the IV during transmission or initialization.

3. Input/Output Alignment (No-Pad Requirement)

Since you’re using no padding, the input to AES must be a multiple of the block size (16 bytes for AES-128). Your JavaCard code constructs a 128-byte messageBytes (8 blocks) which is valid, but:

  • Confirm the encrypted messageBytesEncrypted received in Javax is exactly 128 bytes (no truncation or extra bytes added during APDU transmission).
  • Ensure your Javax decrypt code doesn’t attempt to process a partial block (this would throw an exception in most implementations, but double-check anyway).

4. Byte Order & Transmission Integrity

JavaCard and Javax both use big-endian byte order for crypto operations, but transmission errors can still break things:

  • Capture the raw bytes sent from the card (session key ciphertext + message ciphertext) and compare them to the bytes received in your Javax code. Ensure no bytes are missing, duplicated, or reversed.
  • Verify that the RSA-decrypted session key in Javax matches the first 16 bytes of KEY_SESSION generated in JavaCard (use debug logs or test with a fixed key temporarily if possible).

5. Cipher Algorithm String Mismatch

Make sure your Javax code uses the exact algorithm string that matches JavaCard’s ALG_AES_BLOCK_128_CBC_NOPAD:

// Correct for no-padding CBC mode
Cipher.getInstance("AES/CBC/NoPadding");

Avoid variations like "AES/CBC/PKCS5Padding" or misspelled modes—these will produce incompatible results.

Step-by-Step Verification Test

Isolate the AES operation to narrow down the issue:

  1. In JavaCard, hardcode a fixed 16-byte AES key, all-zero IV, and 128-byte test plaintext.
  2. Encrypt this plaintext and log the ciphertext (or send it over APDU).
  3. In Javax, use the same fixed key, IV, and ciphertext to decrypt. If this works, the problem lies in session key transmission or message construction. If not, double-check your cipher initialization code on both sides.

内容的提问来源于stack exchange,提问作者Ruben Vervaeke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:08:42