【发布时间】:2016-02-05 11:57:01
【问题描述】:
我正在尝试在 JavaCard 环境中实现我自己的 PKCS7 填充方案,以防智能卡不支持 PKCS5 或 7 填充方案。
如果使用对称密码的不同块大小,我希望 PKCS 填充方案的块大小灵活。 length 表示消息输入长度,blocksize 表示密码块的大小。
我的算法将检查 PKCS7 填充中的两种情况,即所有字节是否都是相同的字节(例如 0A, 0A, 0A .. 0A, 0A, 0A),这意味着不涉及填充,并将返回值 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() 无法按预期工作的问题?
我正在实际的 JavaCard 2.2.2 和 JavaCard 3.0.4 兼容智能卡上测试代码,该智能卡处于 OP_READY 模式。
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));
}
}
}
}
}
【问题讨论】:
-
输出
05, 04, 04, 04, 04 ..的确切输入值(length、blockSize)是什么? -
一般建议:不要将
ArrayLogic“重新打包”方法用于您可以通过javacard.framework.Util轻松处理的任务。ArrayLogic方法比Util方法强大得多,但没有理由将它们用于这些非常简单的目的 -Util方法更具可读性并且具有更好的性能。 -
我刚刚注意到,当我调用这些方法时,输入和输出字节数组是相同的,所以它会被混淆和覆盖,所以现在我添加了一个额外的字节数组作为中间缓冲区,这似乎解决了一部分的问题。原始邮政编码尚未更新,因为@Paul Bastian 的回答似乎很有趣,我现在正在查看。
标签: padding smartcard javacard pkcs#7