2015-06-10 13 views
1

這個問題是關係到一個我昨天問:Recovering an ECPublicKey from JavaCard to Java恢復從Java的ECPublicKey以JavaCard的

我有同樣的問題,但以相反的方式: 發送從我的卡公鑰到我的計算機後(該點表示爲按照ANSI X9.62的未壓縮形式的八位字節字符串)我可以恢復相應的鍵。

但是我不能在我的卡上恢復它,如果我從我的電腦發送它,我會得到一個CryptoExceptionILLEGAL_VALUE),這意味着表單不正確或點與曲線參數不匹配。

我覈實,我的參數被明確界定,並在我右邊的形式發送給點...

調試它,我嘗試從我的卡發送公鑰到我的電腦,並將其重新發送到我的卡試圖恢復它(所以我確定參數是好的)。不管結果如何,我仍然得到同樣的錯誤...

爲了說明我的問題,我發佈了相應的代碼:

在卡的一方 - 發送公鑰

pubKey = (ECPublicKey) KeyBuilder.buildKey(
      KeyBuilder.TYPE_EC_FP_PUBLIC, (short) 0x0100, false); 
pubKey.setFieldFP(p, (short) 0x0001, (short) 0x0020); 
pubKey.setA(a, (short) 0x0001, (short) 0x0020); 
pubKey.setB(b, (short) 0x0000, (short) 0x0020); 
pubKey.setR(r, (short) 0x0001, (short) 0x0020); 
pubKey.setG(g, (short) 0x0000, (short) g.length); 

privKey = (ECPrivateKey) KeyBuilder.buildKey(
     KeyBuilder.TYPE_EC_FP_PRIVATE, (short) 0x0100, false); 

KeyPair keypair = new KeyPair(pubKey, privKey); 
    keypair.genKeyPair(); 

short len = pubKey.getW(apduBuffer, (short) 0x0000); 
setOutgoingAndSend((short) 0x0000, len); 

發送的響應是:

APDU <<<: 04C2B28FBE96C5EAC1E81750E9B288B0BD8357D3AED4EA39413197D734B145EBC92F3FD7489B9A7EF4C8A956427668851F0BB3A55D5C7B9033A533F21463E1A2139000 

所以第一座標是x = C2B28FBE96C5EAC1E81750E9B288B0BD8357D3AED4EA39413197D734B145EBC9和第二個,y = 2F3FD7489B9A7EF4C8A956427668851F0BB3A55D5C7B9033A533F21463E1A213

在電腦邊 - 恢復鍵,然後重新發送它

byte[] x = new byte[32]; 
byte[] y = new byte[32]; 
System.arraycopy(W, 1, x, 0, x.length); 
System.arraycopy(W, 1 + x.length, y, 0, y.length); 

ECPublicKeySpec pub = new ECPublicKeySpec(new ECPoint(new BigInteger(1,x), new BigInteger(1,y)), ecParamSpec); 

ECPublicKey ecPubKey = (ECPublicKey) kf.generatePublic(pub); 

byte[] k_x = ecPubKey.getEncoded(); 

byte[] tmp = new byte[70]; 
tmp[0] = (byte) 0x80; 
tmp[1] = (byte) 0x20; 
tmp[2] = (byte) 0x00; 
tmp[3] = (byte) 0x00; 
tmp[4] = (byte) (65); 
System.arraycopy(k_x, k_x.length - 65, tmp, 5,65); 

sendApdu(cardChan, tmp); 

的APDU發送是:

APDU >>>: 802000004104C2B28FBE96C5EAC1E81750E9B288B0BD8357D3AED4EA39413197D734B145EBC92F3FD7489B9A7EF4C8A956427668851F0BB3A55D5C7B9033A533F21463E1A213 

因此,我們不難看出,這是發送的數據是完全相同,以前收到過。

最後,在卡面,我有以下的代碼來恢復的關鍵在於:

pubKey.setW(apduBuffer, ISO7816.OFFSET_CDATA, 
      ISO7816.OFFSET_LC); 

len = pubKey.getW(apduBuffer, (short) 0x0000); 
setOutgoingAndSend((short) 0x0000, len); 

,但我得到APDU >>>: 0401

這意味着CryptoException.ILLEGAL_VALUE是在指令提出

pubKey.setW(apduBuffer, ISO7816.OFFSET_CDATA, 
       ISO7816.OFFSET_LC); 

如何可以把它拋出一個異常,知道我發送我得到pubKey.getW()是一回事嗎?

+0

請問「在響應開始時這個'04'的意思是什麼?」? – Abraham

+0

在對應於從卡公鑰的反應變量: 'APDU <<<:04C2B28FBE96C5EAC1E81750E9B288B0BD8357D3AED4EA39413197D734B145EBC92F3FD7489B9A7EF4C8A956427668851F0BB3A55D5C7B9033A533F21463E1A2139000' 了'04'意味着該點沒有被壓縮,然後你點的2個座標,可以檢查我在開頭提到的鏈接帖子。 關於'APDU >>>:0401',它是一個自制的異常(對於'CryptoException'爲04,對'ILLEGAL_VALUE'爲01)。 – Raoul722

回答

2

這個問題可能:

所有的
pubKey.setW(apduBuffer, ISO7816.OFFSET_CDATA, ISO7816.OFFSET_LC); 

首先,你不應該直接使用ISO7816.OFFSET_CDATAISO7816.OFFSET_LC。使用APDU.getOffsetCData該命令數據的位置,並使用APDU.setIncomingAndReceive獲得數控值(LC是數控價值的編碼)。

由於您使用ISO7816.OFFSET_LC而不是setIncomingAndReceive的輸出,因此目前您的代碼失敗。 ISO7816.OFFSET_LC是一個常數,設置爲值4.您的公開點比這更大。

+1

這是一個接受發生在我的答案之一的新紀錄。恥辱,這是沒有徽章:) –

+0

嗯,我現在確定無疑是盲目的,實際上它需要超過4個字節:) ty – Raoul722

+0

第一個評論是什麼意思?我想在發佈後立即接受答案。我對嗎? :) – Abraham