如何通过Response APDU发送超256字节数据及故障排查
Let's break down your problem step by step and fix it properly: you're trying to send an X.509 certificate over 256 bytes from a JavaCard applet, which triggers APDUException.BAD_LENGTH with standard APDUs. After implementing ExtendedLength and modifying your send logic, you still get an error with status code 0x6F00 (28416), and the host can't receive the certificate to complete verification.
1. Ensure Your Applet Implements ExtendedLength
First, double-check your applet class declaration—you must implement the ExtendedLength interface to enable support for large APDUs. Without this, the JavaCard runtime will reject any extended length operations:
public class YourCertificateApplet extends Applet implements ExtendedLength { // Your applet state (pin, certificate, etc.) }
2. Fix the Certificate Sending Logic
Your modified send_certificate method has two critical flaws:
- A fixed chunk size (240 bytes) that doesn't account for the final partial chunk (causing array out-of-bounds errors, which trigger the
0x6F00status) - Incorrect handling of the host-specified LE (expected response length) value
Here's the corrected method:
private void send_certificate(APDU apdu) { if (!pin.isValidated()) { ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED); } byte[] buffer = apdu.getBuffer(); short certTotalLength = (short) certificate.length; short currentOffset = 0; short chunkSize; // Initialize outgoing channel and get the LE value requested by the host short requestedLE = apdu.setOutgoing(); // Set the actual length to send: use full certificate length if host accepts any length (0xFFFF) or requests more than we have if (requestedLE == 0xFFFF || requestedLE > certTotalLength) { apdu.setOutgoingLength(certTotalLength); } else { // Optional: If host requests less than the full certificate, you can truncate or throw an error // For this use case, we'll send the full certificate regardless apdu.setOutgoingLength(certTotalLength); } // Send the certificate in safe chunks while (currentOffset < certTotalLength) { // Use the smaller of remaining bytes or max compatible buffer size (255 bytes works for most cards) chunkSize = (short) Math.min(certTotalLength - currentOffset, (short) 255); // Copy the chunk to the APDU buffer Util.arrayCopyNonAtomic(certificate, currentOffset, buffer, (short) 0, chunkSize); // Send the chunk apdu.sendBytes((short) 0, chunkSize); currentOffset += chunkSize; } }
Key Fixes:
- Dynamic chunk size: Ensures we never try to copy more bytes than are left in the certificate, eliminating array out-of-bounds errors.
- Proper LE handling: Respects the host's requested length but defaults to sending the full certificate if the host accepts any length.
- Max safe chunk size: 255 bytes is the most compatible chunk size for nearly all JavaCard implementations.
3. Update the Host-Side APDU Request
Your host code sends a standard-length APDU, which doesn't trigger extended length handling on the card. You need to send an extended length APDU by specifying LE = 0xFFFF (tells the card we accept any response length):
// Send extended-length APDU with LE = 0xFFFF (accept any response length) CommandAPDU card_cert = new CommandAPDU(IDENTITY_CARD_CLA, SEND_CERTIFICATE, 0x00, 0x00, new byte[0], 0xFFFF); ResponseAPDU resp4 = c.transmit(card_cert); // Rest of your verification logic remains mostly the same if (resp4.getSW() == 0x9000) { byte[] response = resp4.getData(); // ... your X.509 verification code ... } else { System.out.println("Card error: SW=" + Integer.toHexString(resp4.getSW())); }
If you know the exact certificate length in advance, you can replace 0xFFFF with that length, but 0xFFFF is more flexible.
4. Troubleshooting Tips
- 0x6F00 Error: This almost always means an uncaught runtime exception on the card (like array out-of-bounds). Double-check your certificate array initialization and chunk size calculations.
- Verify Extended Length Support: Some older cards may not support extended length APDUs—confirm your card's specifications.
- Debug Chunk Sending: If possible, use a card debugger or add debug logs to track each chunk's offset and size to ensure they add up to the full certificate length.
内容的提问来源于stack exchange,提问作者Gakuo

