[英]ECDSA algorithm on JCOP 2.4.2 Java Card
I want to implement ECDSA algorithm on Java Card (JCOP 2.4.2). 我想在Java Card(JCOP 2.4.2)上实现ECDSA算法。 This is my source code:
这是我的源代码:
package hashPack;
import javacard.framework.*;
import javacard.security.*;
import javacardx.crypto.*;
public class MyECDSA extends Applet{
private byte[] PLAINTEXT ;
private ECPrivateKey objECDSAPriKey=null; // Object for ECDSA Private Key
private ECPublicKey objECDSAPubKey=null; // Object for ECDSA Public Key
private KeyPair objECDSAKeyPair=null; // Object for ECDSA Key Pair
private Signature objECDSASign=null; // Object for ECDSA Signature
final static short BAS = 0;
final static byte[] SecP192r1_P = { // 24
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xFE,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
final static byte[] SecP192r1_A = { // 24
(byte)0xFC,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xFE,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
final static byte[] SecP192r1_B = { // 24
(byte)0xB1,(byte)0xB9,(byte)0x46,(byte)0xC1,(byte)0xEC,(byte)0xDE,(byte)0xB8,(byte)0xFE,
(byte)0x49,(byte)0x30,(byte)0x24,(byte)0x72,(byte)0xAB,(byte)0xE9,(byte)0xA7,(byte)0x0F,
(byte)0xE7,(byte)0x80,(byte)0x9C,(byte)0xE5,(byte)0x19,(byte)0x05,(byte)0x21,(byte)0x64};
final static byte[] SecP192r1_S = { // 20
(byte)0xD5,(byte)0x96,(byte)0x21,(byte)0xE1,(byte)0xEA,(byte)0x20,(byte)0x81,(byte)0xD3,
(byte)0x28,(byte)0x95,(byte)0x57,(byte)0xED,(byte)0x64,(byte)0x2F,(byte)0x42,(byte)0xC8,
(byte)0x6F,(byte)0xAE,(byte)0x45,(byte)0x30};
final static byte[] SecP192r1_G = { // 25
(byte)0x12,(byte)0x10,(byte)0xFF,(byte)0x82,(byte)0xFD,(byte)0x0A,(byte)0xFF,(byte)0xF4,
(byte)0x00,(byte)0x88,(byte)0xA1,(byte)0x43,(byte)0xEB,(byte)0x20,(byte)0xBF,(byte)0x7C,
(byte)0xF6,(byte)0x90,(byte)0x30,(byte)0xB0,(byte)0x0E,(byte)0xA8,(byte)0x8D,(byte)0x18,(byte)0x03};
final static byte[] SecP192r1_N = { // 24
(byte)0x31,(byte)0x28,(byte)0xD2,(byte)0xB4,(byte)0xB1,(byte)0xC9,(byte)0x6B,(byte)0x14,
(byte)0x36,(byte)0xF8,(byte)0xDE,(byte)0x99,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
final static short SecP192r1_H = 1;
//======================================================================================
public static void install(byte[] bArray, short bOffset, byte bLength){
new MyECDSA(bArray, bOffset, bLength);
}
private MyECDSA(byte bArray[], short bOffset, byte bLength){
PLAINTEXT = new byte[0x100] ; // Data file
Util.arrayFillNonAtomic(PLAINTEXT, BAS, (short)0x100, (byte)0);
register();
}
//======================================================================================
public void process(APDU apdu){
byte buf[] = apdu.getBuffer();
switch(buf[1])
{
//--------------------------------------------------------
case (byte)0xA4: break;
case (byte)0x46:
// Create ECDSA Keys and Pair
/* try {
// <<<<<<<<<<<<<<<< Here is the problem >>>>>>>>>>>>>>>>>
objECDSAPriKey = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE, KeyBuilder.LENGTH_EC_FP_192, true);
}
catch(CryptoException c)
{
short reason = c.getReason();
ISOException.throwIt(reason); // for check
} // for check*/
// objECDSAPubKey = (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, KeyBuilder.LENGTH_EC_FP_192, true);
// set EC Domain Parameters
objECDSAPubKey.setFieldFP(SecP192r1_P, BAS, (short)24);
objECDSAPubKey.setA(SecP192r1_A, BAS, (short)24);
objECDSAPubKey.setB(SecP192r1_B, BAS, (short)24);
objECDSAPubKey.setG(SecP192r1_G, BAS, (short)25);
objECDSAPubKey.setK(SecP192r1_H);
objECDSAPubKey.setR(SecP192r1_N, BAS, (short)24);
objECDSAKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_192);
// On-Card Key Generation Process
objECDSAKeyPair.genKeyPair();
// Obtain Key References
objECDSAPriKey = (ECPrivateKey)objECDSAKeyPair.getPrivate();
objECDSAPubKey = (ECPublicKey)objECDSAKeyPair.getPublic();
// Create Signature Object
objECDSASign = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
break;
case (byte)0x2E:
short Le = apdu.setOutgoing();
short sSignLen=0 ;
// Init with Private Key
objECDSASign.init(objECDSAPriKey, Signature.MODE_SIGN);
// Sign Data
sSignLen = objECDSASign.sign(PLAINTEXT, BAS, Le, buf, BAS);
apdu.setOutgoingLength(sSignLen);
apdu.sendBytes(BAS, sSignLen);
break;
//--------------------------------------------------------
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
return;
}
}
I am running this source code using this script script code: 我正在使用以下脚本脚本代码运行此源代码:
#/term SCComm:2
/mode trace=on
/atr
/card
/select |ecdsa
/send 00A4040007D4106509900090
/send 0046000000
/send 002E00000A30313233343031323334
When I am calling /send 0046000000
for signing the plain text message I get the response code 6F00
. 当我致电
/send 0046000000
签署纯文本消息时,我得到响应代码6F00
。
Could you help me to find out what is wrong with this? 您能帮我找出问题所在吗?
How to properly implement this algorithm on a JCOP card? 如何在JCOP卡上正确实现此算法?
I'm not an expert on JCOP but I have experience with ISO7816: 我不是JCOP的专家,但是我具有ISO7816的经验:
Statusword 0x6F00 means "General Error". 状态字0x6F00表示“常规错误”。 I suppose a CryptoException is thrown, but the value of "reason" is between 1-5 (according to the documentation ).
我想抛出了CryptoException,但是“ reason”的值在1-5之间(根据文档 )。 It's not possible to return arbitrary values as ISO7816 statusword.
无法返回任意值作为ISO7816 statusword。
Therefore I would suggest to send the reason using apdu.sendBytes(...), then you know what really is the problem 因此,我建议使用apdu.sendBytes(...)发送原因,然后您知道真正的问题是什么
Best way would be to debug the code 最好的方法是调试代码
Since you indicate that your call to KeyBuilder.buildKey(...)
fails, I would assume that this call throws a CryptoException
with reason code NO_SUCH_ALGORITHM
. 由于您指示对
KeyBuilder.buildKey(...)
调用失败,因此,我假定此调用将引发CryptoException
,原因码为NO_SUCH_ALGORITHM
。 As you do not handle that exception in your code, this results in the status word 0x6F00
being retuned by the card ( 0x6F00
is typically returned in case of unhandled exceptions). 由于您未在代码中处理该异常,因此会导致状态字
0x6F00
被卡重新调整(如果未处理异常,通常会返回0x6F00
)。
So the CryptoException
indicates that the requested key algorithm is not supported. 因此
CryptoException
指示不支持请求的密钥算法。 Since you use the following parameters 由于您使用以下参数
KeyBuilder.buildKey(
KeyBuilder.TYPE_EC_FP_PRIVATE, // key type
KeyBuilder.LENGTH_EC_FP_192, // key length
true); // key encryption
this could mean that 这可能意味着
As the FIPS 140-2 Cryptographic Module Security Policy for both JCOP 2.4.2 R2 and JCOP 2.4.2 R3 indicate that ECDSA key pair generation is supported for P-192 (besides P-224 and P-256), I would assume that your card does not support key encryption. 由于同时针对JCOP 2.4.2 R2和JCOP 2.4.2 R3的FIPS 140-2加密模块安全策略表明P-192支持ECDSA密钥对生成(P-224和P-256除外),因此我认为您的卡不支持密钥加密。 Hence, you could instead try
因此,您可以尝试
KeyBuilder.buildKey(
KeyBuilder.TYPE_EC_FP_PRIVATE, // key type
KeyBuilder.LENGTH_EC_FP_192, // key length
false); // key encryption
I can see two different issues: 我可以看到两个不同的问题:
Furthermore it should be noted that: 此外,应注意:
KeyBuilder
(currently commented out); KeyBuilder
构建公共密钥(当前已注释掉); ISOException
with a valid status word; ISOException
;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.