2016-02-01 53 views
0

我試圖在JavaCard環境中實現自己的PKCS7填充方案,以防智能卡不支持PKCS5或7填充方案。JavaCard中的PKCS7填充

我希望在使用對稱密碼的不同塊大小的情況下,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()未按預期工作的問題?

我正在測試在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)); 
       } 
      } 
     } 
    } 
} 
+0

什麼是輸出05,04,04,04,04 ..的確切輸入值('length','blockSize')? – vojta

+1

一般建議:不要對'javacard.framework.Util'容易處理的任務使用'ArrayLogic'「重新打包」方法。'ArrayLogic'方法比'Util'方法強大得多,但沒有理由將它們用於這些非常簡單的目的 - 'Util'方法更具可讀性並且具有更好的性能。 – vojta

+0

我剛剛注意到當我調用方法時,輸入和輸出字節數組是相同的,所以它被混合並覆蓋,所以現在我添加了一個額外的字節數組作爲似乎解決部分問題的中間緩衝區。原來的郵政編碼沒有更新,因爲@Paul Bastian的答案似乎很有趣,我現在正在查看它。 – thotheolh

回答

1

嗯,我不認爲這就是唯一的錯誤,但你的分支是definitly錯誤:

// 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) { 

你是比較合適的長度,但錯誤的偏移。

我不明白你的方法應該做什麼。如果填充錯誤應該拋出一個錯誤?

+0

else case處理了你有0A,0B,0C,0D,08,08,08,08,08,08,08,08的情況。最後的8個字節看起來幾乎像一個08 pad,但是由於它是07不考慮pad,所以else子句捕獲並聲明它不是一個合適的pad,並且簡單地將輸入結果作爲輸出返回而不進行修改。 – thotheolh

+0

那麼它解決了你的問題? –

+0

是的,問題的一部分是錯誤的變量用於補償和許多其他小函數的bug。我會更新問題以包含實際的工作答案。 – thotheolh