Javacard 中的 ECDSA 签名

2024-04-09

我正在 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

我的开发环境如下。

  • 操作系统:Windows 7
  • JCDK 版本 2.2.1
  • JDK 版本 1.4.2
  • 芯片:恩智浦
  • 终端:ACR122 NFC非接触式智能卡读卡器

我更改了代码来设置域参数。但卡仍然输出相同的结果(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 域参数。需要创建KeyPair使用一个ECPublicKey and a ECPrivateKey为其设置域参数(因此点 W 和秘密 S 可以保留为空)。之后就可以调用genKeyPair(),至少如果卡支持 F(2m) 或 F(p) 椭圆曲线加密以及指定的密钥大小。


ADDED

请注意,NXP JCOP 芯片可能需要为公众设置这些参数和私人的钥匙。参数应该具有密钥大小(对于单独的值)或未压缩的椭圆曲线点。题中G的值好像是一个压缩点。仅辅因子(对于setH) 的值为 1。

请注意,只有具有非对称协处理器的芯片才可能支持椭圆曲线;并非所有卡的创建/配置都是相同的。请联系您的供应商了解详细信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Javacard 中的 ECDSA 签名 的相关文章

  • 如何在java中压缩/解压tar.gz文件

    谁能告诉我在java中压缩和解压缩tar gzip文件的正确方法我一直在搜索 但我能找到的最多的是zip或gzip 单独 我写了一个包装器公共压缩 http commons apache org compress called jarchi
  • Java Sqlite Gradle

    我对 gradle 和 java 还很陌生 我有一个使用 sqlite 的项目 它通过 intellij idea 运行良好 但我无法从终端运行它 它会抛出异常 java lang ClassNotFoundException org sq
  • 在 Tomcat 上部署 Java Web 项目,无需 WAR 或 EAR

    我有一个 Java Web 项目 Struts Spring 在我的本地主机上完美运行 我必须将其部署在我的网站上 但虚拟主机提供的 Tomcat Manager 界面显示 由于安全原因 它无法上传 WAR 文件 当联系技术支持时 我被告知
  • WebLogic 10 中的临时目录

    每当 WL 停止时 它都不会删除其临时目录 即 domains mydomain servers myserver tmp WL TEMP APP DOWNLOADS domains mydomain servers myserver tm
  • Maven 目标的默认阶段?

    据我了解 在 Maven 中 插件目标可以附加到生命周期阶段 如果没有定义 默认阶段是什么 根据我的经验 这取决于插件的目标 例如 组装 单个 http maven apache org plugins maven assembly plu
  • org.postgresql.util.PSQLException:协议错误。会话设置失败

    我知道这些类型的问题已经存在 但提供的解决方案对我不起作用 在我的应用程序中 没有版本不匹配的黑白驱动程序和 PostgreSQL 服务器 我还没有找到任何其他解决方案 我正在使用 PostgreSQL 服务器 9 4 和 postgres
  • FFmpeg 不适用于 android 10,直接进入 onFailure(String message) 并显示空消息

    我在我的一个项目中使用 FFmpeg 进行视频压缩 在 Android 10 Google Pixel 3a 上 对于发送执行的任何命令 它会直接进入 onFailure String message 并显示空消息 所以我在我的应用程序 g
  • 此版本不符合 Google Play 64 位要求,添加库后仍然出现错误

    我正在 Play 商店上传一个视频编辑器应用程序 其中包含带有一些本机代码的库 所以我通过将其添加到 gradle 来使其兼容 64 位 ndk abiFilters armeabi v7a arm64 v8a x86 x86 64 添加了
  • 如何使用 BufferedReader 对象从 Java 中的一行读取多个整数值?

    我正在使用 BufferedReader 类读取 Java 程序中的输入 我想读取用户的输入 该用户可以在带空格的单行中输入多个整数数据 我想读取整数数组中的所有这些数据 输入格式 用户首先输入他 她想要输入的数字数量 然后在下一行中使用多
  • Java 中 static 关键字如何工作?

    我正在阅读Java教程 http docs oracle com javase tutorial index html从一开始我就有一个问题static字段或变量上的关键字 作为Java said here http docs oracle
  • Kerberos 缓存票证

    我使用的是 Windows 7 64 位 我创建了一个简单的应用程序来对实现 PrivilegedAction 的类的 run 方法中的文件进行计数 以下是我的 jaas conf 文件 CountFiles com sun securit
  • 删除 ArrayList 对象问题

    我在处理作业时遇到从 ArrayList 中删除对象的问题 如果我使用 正常 for 循环 它的工作原理如下 public void returnBook String isbn for int i 0 i lt booksBorrowed
  • 在 netBeans 中运行程序时,字体看起来非常奇怪

    我在我的新 MacBook M1 上设置了 netBeans 和 SceneBuilder 除了运行程序时的字体外 一切正常 它看起来像这样 我不知道为什么 按钮应显示 Click me 标签应显示 Hello 我收到的错误消息是 M rz
  • setKeyListener 将覆盖 setInputType 并更改键盘

    大家好 我在两个设备之间遇到问题 在实践中使用InputType和KeyListener我正在操纵一个EditText让它从数字键盘接收逗号和数字 有关更多背景信息 请检查我之前的question https stackoverflow c
  • 如何使用 Hibernate Session.doWork(...) 进行保存点/嵌套事务?

    我正在使用 JavaEE JPA 托管事务与 Oracle DB 和 Hibernate 并且需要实现某种嵌套事务 据我所知 此类事情不受开箱即用的支持 但我应该能够为此目的使用保存点 正如建议的https stackoverflow co
  • 使用 Cucumber Scenario Outline 处理 Excel 电子表格

    如果可能的话 我试图找到一种更优雅的方法来处理从与 Excel 电子表格行 第 n 个 相关的 Cucumber Scenario Outline 中调用第 n 个数字 目前 我正在使用迭代编号来定义要从中提取数据的 Excel 电子表格的
  • 无法在 BlackBerry Playbook 上设置音量

    我在更改黑莓游戏书的音量时遇到问题 首先 我将 Android 应用程序重新打包到 Palybook 应用程序 我需要使用搜索栏更改黑莓剧本的音量 并在搜索监听器中设置音频管理器音量 这是代码 audioManager AudioManag
  • SWT - 与操作系统无关的获取等宽字体的方法

    SWT 有没有一种方法可以简单地获得跨各种操作系统的等宽字体 例如 这适用于 Linux 但不适用于 Windows Font mono new Font parent getDisplay Mono 10 SWT NONE 或者我是否需要
  • 编译时在代码中替换Java静态最终值?

    在java中 假设我有以下内容 fileA java class A public static final int SIZE 100 然后在另一个文件中我使用这个值 fileB java import A class b Object t
  • RecyclerView 不调用 onCreateViewHolder 或 onBindView

    没有收到任何错误 所有数据似乎都有效 由于某种原因 没有调用与视图相关的方法 我已确定以下事项 getItemCount 是唯一被调用的适配器方法 并且返回一个正整数值 我知道这将是你们将要查看的区域 构造函数正在被调用 成员变量有效 Pa

随机推荐

  • 等待进程组时 waitpid() 无子进程错误

    编写我自己的玩具外壳 并在尝试实现作业控制时遇到了障碍 我正在使用 setpgid 在子进程和父进程中设置子进程组 我的等待电话是 pid waitpid pid status 0 然而 waitpid 返回 1 并且 perror 说 没
  • 从 unicode 字符串中去除特殊字符和标点符号

    我正在尝试从 unicode 字符串中删除标点符号 该字符串可能包含非 ASCII 字母 我尝试使用regex module import regex text u lt ik gt regex sub ur p P text 然而 我注意
  • Julia DataFrames 中的高效自定义排序?

    有没有一种快速的方法来指定自定义订单sort sort 在 Julia 数据框架上 julia gt using DataFrames julia gt srand 1 julia gt df DataFrame x rand 10 y r
  • WS02 ESB 中的 HL7 传输安全吗?

    我的小组正在评估 HL7 代理并遇到了 WS02 ESB 我已经成功配置了一个看起来运行良好的 HL7 代理 现在我的任务是使用 SSL 特别是 TLS 保护监听点 这似乎是 ESB 应该能够处理的事情 它可以执行 HTTPS 安全 Web
  • EditText android:提示不会在焦点上消失

    我使用的是 Android 4 我正在尝试向我的编辑文本小部件添加提示 我尝试将提示添加到布局中 如下所示
  • Bootstrap 4 - 垂直居中列表项

    我有一个使用 Bootstrap 4 beta 的网页 在此页面中 我有一个内联列表 我希望每个列表项的内容垂直居中 以便项目对齐 如图所示Bootply https www bootply com od2qnkLIkQ 它们目前偏离中心
  • Heroku:错误 R10(启动超时)-> Web 进程无法在启动后 60 秒内绑定到 $PORT - Python

    我正在尝试托管一个使用张量流到heroku的瓶子应用程序 应用程序启动 我得到了 服务器在端口上运行 以及 但应用程序未打开 大约一分钟后 它显示以下跟踪 打开跟踪表明服务器运行成功 2018 08 25T19 46 55 651043 0
  • Symfony 内存问题

    我在 symfony 和 cpu 内存泄漏方面遇到了困难 我是 symfony 的新手 我不知道我是否弄乱了任何技巧或技术来克服这个问题 我在 vps 上托管我当前的 symfony 项目 它几乎每隔一小时就会停止一次 我也想知道这些问题的
  • 如何在jquery中将html2canvas图像保存到系统文件夹中

    我有一个 id form1 的表单 在这个表单中我有一个图表 现在我使用 html2canvas 来获取此 form1 的图像 这是我的代码
  • 带有图标相对路径的 Windows 快捷方式

    有没有办法设置Windows快捷方式中图标的相对路径 对于目标位置 它工作正常 windir system32 cmd exe c cd CD start fileToExecute bat 我读到 win 快捷方式可以自动从 exe 文件
  • Android JavaCV 困境,创建 IplImage 时在“draw”方法中抛出 NoClassDefFoundError

    我正在使用 JavaCV 库和针对 Android 的预构建 OpenCV 库 我认为我已经以正确的方式设置了 Eclipse 因为我已经包含了 javacv jar 和 javacpp jar 两个 jar 另外 java cv andr
  • 如何将项目添加到SqlDataSource数据绑定列表

    我很懒 我正在使用 SQLDataSource 来填充我的下拉列表 数据绑定对象的 Databind 事件在 Page PreRender 之前调用 因此我在 PreRender 事件处理程序中执行类似的操作 private void In
  • assertThat - hamcrest - 检查列表是否已排序

    好吧 我认为这将是一个简短的问题 我有一个按日期排序的 ArrayList 当然我看到它有效 但我也想为它编写一个测试 我想检查列表中的下一个值 日期 是否低于前一个值 我可以使用一些来做到这一点fors 并添加临时列表 但我想知道是否有更
  • 如何使用 WiX 安装和启动 Windows 服务

    我尝试在 Wix 中使用下面的代码 但是在安装时 安装程 序在 正在启动服务 状态下冻结了大约 3 分钟 然后我收到此消息 Service Jobservice 无法启动 请验证您是否有足够的权限来启动系统服务 我的代码有什么错误吗 并且可
  • Gradle:将多个项目打包到一个jar中

    我有一个 gradle 多项目 想要创建一个包含子项目和外部依赖项的所有类的单个 jar 库 我有以下项目结构 每个项目都有自己的第 3 方依赖项 常见的依赖项包含在根项目中 两个模块A和B都依赖于核心 root project only
  • Scala:计算标准差的通用方法是什么

    我很好奇如何编写一个通用方法来计算 scala 中的标准差和方差 我有一个计算平均值的通用方法 从这里窃取 在 Scala 中编写通用均值函数 https stackoverflow com questions 6188990 writin
  • 为什么 Qt 无法识别我的头文件?无法打开包含文件 没有这样的文件或目录

    我的 pro 文件中有以下内容 并且我有以下文件 include headerhere 例如 include StdAfx h 不过我得到了 错误无法打开包含文件 StdAfx h 没有这样的文件或目录 无论我使用还是出现同样的错误 inc
  • 如何更新嵌套对象数组的值

    这是我的实际数组 let mainArray value AG TURF 123 label Ag Turf checked false id 123 children value AG TURF 123 TRACTOR 456 label
  • 自定义View可以知道onPause已经被调用了吗?

    我有一个运行线程操作的自定义视图 该操作定期调用互联网 我想知道是否有一种方法可以让我不必从父 Activity onPause 中杀死该线程 以便在 Activity 后台运行 和 或杀死 后 线程不会在后台闲逛 这里的目的是让自定义视图
  • Javacard 中的 ECDSA 签名

    我正在 Javacard 中使用 ECDSA 实现签名代码 我的代码在异常部分输出 0x0003 NO SUCH ALGORITHM 这意味着该卡不支持该算法 我不明白这一点 因为我的供应商告诉我它支持 ECC 我的结论是 我不知道如何使用