JavaCard 中的 PKCS7 填充

PKCS7 Padding in JavaCard

我正在尝试在 JavaCard 环境中实现我自己的 PKCS7 填充方案,以防智能卡不支持 PKCS5 或 7 填充方案。

如果使用不同块大小的对称密码,我希望 PKCS 填充方案的块大小灵活。 length 表示消息输入长度,blocksize 表示密码块的大小。

我的算法将检查 PKCS7 填充中的两种情况,即所有字节是否都是相同的字节(例如 0A, 0A, 0A .. 0A, 0A, 0A),这意味着不涉及填充并且 return 值 0.

第二种情况是检查是否有填充(例如0A, 0B, 0C, 05, 05, 05, 05, 05)。

所有的场景我都可以检查成功,但是在复制数据输出结果的时候,好像没有复制正确。

似乎在调用 arrayCopyRepackNonAtomic() 之前填充的 arrayFillGenericNonAtomic() 数据仍然停留在输出字节数组中,并且执行 arrayCopyRepackNonAtomic() 没有正确复制数据。

我使用的输出字节数组格式是数组中的第一个元素携带已处理输出数据量的指示符(以字节表示)(例如 output[outputOffset] = (byte) 0x10 表示 16后处理的数据元素)。输出字节数组中第一个元素包含已处理数据后的后续数据元素。

问题的一个例子是我正在尝试 PKCS7 解码 A0, B0, C0, D0, E0, 04, 04, 04, 04 并且结果应该是 05, A0, B0, C0, D0, E0(其中 05 表示处理了以下 5 个字节)但我得到 05, 04, 04, 04, 04 .. 代替。

如何解决 arrayCopyRepackNonAtomic() 未按预期工作的问题?

我正在 OP_READY 模式下的实际 JavaCard 2.2.2 和 JavaCard 3.0.4 兼容智能卡上测试代码。

public static void process(byte[] input, short offset, short length,
        short blockSize, byte[] output, short outputOffset, short mode) {
    if (mode == MODE_DECODE) {
        // Data length must be >= blocksize and have to have be a modulus of 0 size.
        if ((length >= blockSize) && ((length % blockSize) == 0)) {
            output[outputOffset] = (byte) length;
            ArrayLogic.arrayFillGenericNonAtomic(output, (short) (outputOffset + 1), (short) (length - 1), output, outputOffset);
            if (ArrayLogic.arrayCompareGeneric(input, offset, output, outputOffset, length) == 0x00) {
                // If all bytes are the same, return 0.
                output[outputOffset] = (byte) 0x00;
            } else {
                // Bytes are not all the same, check if the last segment of bytes are padded.
                if (ArrayLogic.arrayCompareGeneric(input, offset, output, outputOffset, (short) (input[(short) (offset + length - 1)] & 0xFF)) == 0x00) {
                    // Padded bytes are found.
                    output[outputOffset] = (byte) (length - input[(short) (offset + length - 1)]);
                    // Unable to copy correctly to output
                    ArrayLogic.arrayCopyRepackNonAtomic(input, offset, (short) (output[outputOffset] & 0xFF), output, (short) (outputOffset + 1)); 
                } else {
                    output[outputOffset] = (byte) length;
                    // Unable to copy correctly to output
                    ArrayLogic.arrayCopyRepackNonAtomic(input, offset, length, output, (short) (outputOffset + 1));
                }
            }
        }
    }
}

问题已解决,问题是错误的变量偏移量以及导致问题的字节到短转换的处理。

下面是一个工作版本,在对那些有兴趣在未来使用它的人进行一些测试后,它似乎可以进行填充。

public static void process(byte[] input, short offset, short length,
        short blockSize, byte[] workBuff, short buffOffset, byte[] output,
        short outputOffset, short mode) {
    if (mode == MODE_DECODE) {
        // Data length must be >= blocksize and have to have be a modulus of 0 size.
        if ((length >= blockSize) && ((length % blockSize) == 0)) {
            workBuff[buffOffset] = (byte) input[(short) (length + offset - 1)];
            ArrayLogic.arrayFillGenericNonAtomic(workBuff, buffOffset, length, workBuff, buffOffset);
            if (ArrayLogic.arrayCompareGeneric(input, offset, workBuff, buffOffset, length) == 0x00) {
                // If all bytes are the same, return 0.
                output[outputOffset] = (byte) 0x00;
            } else {
                output[outputOffset] = (byte) (offset + length - (workBuff[buffOffset] & 0xFF));
                output[(short) (outputOffset + 1)] = workBuff[buffOffset];
                // Bytes are not all the same, check if the last segment of bytes are padded.
                if (ArrayLogic.arrayCompareGeneric(input, (short) (offset + length - (workBuff[buffOffset] & 0xFF)), workBuff, buffOffset, (short) (workBuff[buffOffset] & 0xFF)) == 0x00) {
                    // Padded bytes are found.
                    output[outputOffset] = (byte) (length - input[(short) (offset + length - 1)]);
                    ArrayLogic.arrayCopyRepackNonAtomic(input, offset, (short) output[outputOffset], output, (short) (outputOffset + 1));
                } else {
                    // Padded bytes are not found.
                    output[outputOffset] = (byte) length;
                    ArrayLogic.arrayCopyRepackNonAtomic(input, offset, length, output, (short) (outputOffset + 1));
                }
            }
        }
    }
}

嗯,我不认为这是唯一的错误,但你的分支绝对是错误的:

// Bytes are not all the same, check if the last segment of bytes are padded.
if (ArrayLogic.arrayCompareGeneric(input, offset, output, outputOffset, (short) (input[(short) (offset + length - 1)] & 0xFF)) == 0x00) {

您比较的长度正确,但偏移量错误。

我不明白 else-case 在你的方法中应该做什么。如果填充错误应该抛出错误?