JavaCard中的PKCS7填充

时间:2016-02-01 06:16:15

标签: padding smartcard javacard pkcs#7

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

我希望在使用不同块大小的对称密码的情况下,PKCS填充方案的块大小是灵活的。 length表示邮件输入长度,blocksize表示密码块的大小。

我的算法会检查PKCS7填充中的两个场景,即所有字节是否都是相同的字节(例如0A, 0A, 0A .. 0A, 0A, 0A),这意味着没有涉及填充并返回值0

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

我能够成功检查所有方案,但是当复制数据以输出结果时,它似乎无法正确复制。

似乎在调用arrayFillGenericNonAtomic()之前填充的arrayCopyRepackNonAtomic()数据仍然停留在输出字节数组中,并且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));
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分: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) {

您正在比较正确的长度,但错误的抵消。

我不明白你的方法应该做什么。如果填充错误会抛出错误吗?