- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在 Javacard 中使用 ECDSA 实现签名代码。
我的代码在异常部分输出 0x0003(NO_SUCH_ALGORITHM),这意味着这张卡不支持该算法。我不明白,因为我的供应商告诉我它支持 ECC。我得出结论,我不知道如何使用 ECDSA 签名,但我想知道。
这是我的完整源代码
package MyECDSA;
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;
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 >>>>>>>>>>>>>>>>>
objECDSAKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_192);
//objECDSAKeyPair = new KeyPair(KeyPair.ALG_EC_F2M, KeyBuilder.LENGTH_EC_F2M_193);
}
catch(CryptoException c)
{
short reason = c.getReason();
ISOException.throwIt(reason);
}
ISOException.throwIt((short)0x9999); // for check
// Generate Key pair
objECDSAKeyPair.genKeyPair();
// Create Signature Object
objECDSASign = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
objECDSAPriKey = (ECPrivateKey)objECDSAKeyPair.getPrivate();
objECDSAPubKey = (ECPublicKey)objECDSAKeyPair.getPublic();
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;
}
}
而APDU命令如下
[ Card ] <== 00A4040007D4106509900090
[ Card ] ==> 9000
[ Card ] <== 0046000000
[ Card ] ==> 0003
我的开发环境如下。
我更改了我的代码以设置域参数。但是卡仍然输出相同的结果(0x0003)。这是我的完整源代码。
package MyECDSA;
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, false);
ISOException.throwIt((short)0x8888); // for check
objECDSAPubKey = (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, KeyBuilder.LENGTH_EC_FP_192, false);
// 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);
}
catch(CryptoException c)
{
short reason = c.getReason();
ISOException.throwIt(reason); // for check
}
// 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;
}
}
最佳答案
Java Card 中没有默认的 EC 域参数。需要使用设置域参数的 ECPublicKey
和 ECPrivateKey
创建 KeyPair
(因此点 W 和 secret S 可能留空)。之后就可以调用 genKeyPair()
,至少如果卡支持 F(2m) 或 F(p) 椭圆曲线加密和指定的 key 大小。
已添加
请注意,恩智浦 JCOP 芯片可能需要为公钥和私钥设置这些参数。参数应具有 key 大小(对于单独的值)或未压缩 椭圆曲线点。题中G的值好像是一个压缩点。只有辅助因子(setH
)的值应该为 1。
请注意,只有具有非对称协处理器的芯片才可能支持椭圆曲线;并非所有卡片的创建/配置都是一样的。有关详细信息,请联系您的供应商。
关于java - Javacard 中的 ECDSA 签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24467612/
我已经开始使用 JavaCards 并试图掌握 CLA 字节的含义。 如果阅读RFC 5.4.1 Class byte 5.4.1 Class byte According to table 8 us
我有一张 Gemalto Top DL v2 java 卡。当我 list 内容时,卡中加载了很多包: GlobalPlatformPro:> gp -visa2 -key 47454D5850524
我想读取 Java 卡上的 TLV 编码证书(NXP JCOP J3D081、JCOP 版本 2.4.2、Java 卡版本 3.0.1 Classic)。 cap 文件已成功创建,但当我尝试将其安装到
我想知道 JavaCard 中的 Util.* 函数是否通常是抗侧 channel 的。 是否存在一些具有侧 channel 抗性 Util.* 功能的 JavaCard? 我查看了几个公共(publ
我想配置一个 JavaCard,以便它只允许安装由特定 key 签名的小程序。我不确定这个签名是否是 cap 文件格式的一部分。我已经可以通过 GlobalPlatformPro 中的代码从 Andr
在尝试反编译 capfile 时研究 JCVM 规范,我想到了以下问题: 描述符组件(6.13)说: The Descriptor Component provides sufficient info
如您所知,OTA 消息或无线消息是特制的二进制 SMS 消息,移动运营商使用这些消息向 SIM 卡发送 APDU 命令以进行管理。例如,他们可以使用此类消息在 SIM 卡上安装或删除小程序。 我想知道
我正在寻找一个使用Java Card在SIM卡上运行的简单初学者程序。谁能给我一些入门的基本信息?我已经看过一些关于工具包api的描述,但是我正在寻找类似的东西:sim卡支持哪些功能,如何将我的代码上
我有一个空的 Javacard,如下所示: user@system$ java -jar gp.jar --list ISD: A000000003000000 (OP_READY) Pri
我是智能卡开发的新手。请帮助我了解如何开始。 Javacard和JCOP之间有什么关系? 如何将JCOP版本映射到GlobalPlatform Card Specification? 例如,JCOP
我正在尝试理解java卡的概念,我有一些疑问,我想与大家分享,也许你能给我任何最好的建议。 //Jcop- 我在某处读到 Java Card OpenPlatform (JCOP) 是由 IBM Zü
java卡现在有什么用?该文档要么非常旧,要么非常稀疏。谷歌搜索了一段时间后,这是我的想法: eID:使用私钥签署文档哈希,由中央机构(政府)颁发 - 签署法律文件 唯一 ID - 通过 ID 识别(
我想在 Linux 计算机上生成证书,将其传输到卡并在那里加密。然后将其存储并稍后取回。我想知道如何在卡上获取 4k RSA 数据之类的东西。它可以与 APDU 配合使用吗? 最佳答案 证书一般不需要
我尝试使用oracle java card development kit 3.0.5u2命令行工具。 我用的是netbeans生成的cap文件 我用 verifycap.bat在我的帽子上以及 sd
有人可以给我一些关于如何使用 javacard 签名并验证它的小建议吗?我想我在签名生成和验证方面做错了: ... SignatureMessageRecovery sig; ... private
我正在尝试在卡上签署一条消息并在卡外验证它。 结果总是假的。 我可能获取的模数和指数不正确。有什么想法吗? Java 小程序代码: protected MainApplet() { try {
我想开发一个使用 java 卡的生物识别指纹认证,我发现 javacard 2.2 提供了 APIs (javacardx.biometry) 来做到这一点,但我没有找到任何关于Match On Ca
我注意到我的智能卡(带有 Omnikey 5121 读卡器的 NXP J2E145、J3A081、J3C145)上出现了一些非常奇怪的行为:调用 JavaCard 方法后立即断电 JCSystem.r
我有一个包含我的小程序的双接口(interface) Java 卡。我想对来自不同接口(interface)的单个命令有两个不同的 APDU 响应。 例如,当从接触界面接收到命令时,我想用“Con
我一直在查看 JavaCard API 和示例,但找不到对更高级别数据集合(如 List、ArrayList、HashMaps 等)的任何引用? 我错过了什么吗? 我知道 JavaCard 环境的资源
我是一名优秀的程序员,十分优秀!