2012-12-05 54 views
5

我有自簽名證書由SHA1withECDSA算法使用BouncyCastle。 在卑詩省我可以很容易地驗證它,但是當我在JavaCard上這樣做時,它每次都會發送給我false(來自NIST的曲線secp192r1)。證書持有登錄平原(非X9.62意味着只有R + S沒有任何標籤)。驗證SHA1withECDSA簽名在javacard

有我的代碼來驗證它(值作爲常量 - 當然測試)。

字節[] certdata = {...}

Signature signature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false); 
    ECPublicKey ecpk = (ECPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC,  KeyBuilder.LENGTH_EC_FP_192, true); 

    ecpk.setA(new byte[]{...}, (short)0, (short)0x0018); 
    ecpk.setB(new byte[]{...}, (short)0, (short)0x0018); 
    ecpk.setG(new byte[]{...}, (short)0, (short)0x0031); 
    //Point format: uncompressed tag(0x04), x, y 
    ecpk.setK((short)0x0001); 
    ecpk.setR(new byte[]{}, (short)0, (short)0x0018); 
    ecpk.setW(new byte[]{}, (short)0, (short)0x31); 
    ecpk.setFieldFP(new byte[]{}, (short)0, (short)0x0018); 

    signature.init(ecpk, Signature.MODE_VERIFY); 

    boolean result = signature.verify(certdata, (short)0, (short)certdata.length, signtab, (short)0, (short)signtab.length); 
    if(result) ISOException.throwIt((short)0x0001); 
    else ISOException.throwIt((short)0x0002);  
} 

'...',而不是爲清晰視圖(192bits曲線可以做很大的混亂)字節。

證書與引擎收錄標籤說明:

http://pastebin.com/gvqYzm2g

感謝所有幫助

sevar

編輯: 新的測試: 所有測試重新在相同的數據(公鑰,專用密鑰,要簽名的消息) 符號是隨機的,所以我將使用2符號(signT - 由終端(BC)生成的符號,signC - 生成符號d by Chip)

signT不能在CHIP上驗證,但可以在終端上驗證。 signC是片驗證&終端

所以我API之間交叉檢查

  • 針對BC交叉關係行之有效

  • 指向CHIP交叉關係是不行的

對生成的密鑰很好,因爲當我把由BC生成的PrivateKey和PublicKey發送給CHIP時,那麼s芯片上生成的信號可以通過CHIP驗證。

  • 密鑰對生成以及

我不知道我應該怎麼檢查。問題可能是在ECDSA step e = SHA1(Message)中填充數組。散列之後發生什麼事(散列比曲線短,卡片需要在複製之前聲明陣列的大小)

+1

你怎麼看這個sevar?如果您提供意見/回答等的反饋意見,這將很好。 –

回答

0

從Bouncy Castle到JavaCard的Prime192v1簽名和驗證ECDSAwithSHA-1適用於我。

你的問題可能是簽名本身的格式。

簽名是DER編碼結構,它是兩個整數(標記0x02)的序列(標記0x30)。在JavaCard中,始終需要56個字節:長度爲25的兩個座標加上DER頭的6個字節。 JavaCard總是期望每個座標中的前導零。但是,BC通常會生成簽名而座標中不包含前導零,因此簽名可能少於56個字節,這就是JavaCard混淆的原因。

反方向總是可以的,因爲BC可以處理前導零,儘管它在創建簽名時不會添加它們。

你應該做什麼:用你自己的代碼包裝BC簽名機制,並總是在BC簽名中添加前導零到座標。如果您這樣做,您將能夠在BC和JavaCard中驗證簽名。

我想後我的代碼,但不幸的是它是一個商業安全項目的一部分......