RSA密钥生成在JCARD 2.2.2上失败

时间:2014-05-01 01:26:55

标签: java eclipse rsa javacard apdu

我是JCard编程的初学者(2天经验......),我试图在CREF模拟卡上部署应用程序,生成RSA KeyPair并将公钥发送给主机RMI客户端应用程序,不知何故,当我从客户端应用程序启动init方法时,我得到了这个例外:

Exception in thread "main" java.lang.UnsatisfiedLinkError:
com.sun.javacard.impl.NativeMethods.getCurrentContext()B
at com.sun.javacard.impl.NativeMethods.getCurrentContext(Native Method)
at com.sun.javacard.impl.PrivAccess.getCurrentAppID(PrivAccess.java:454)
at javacard.framework.CardRuntimeException.<init>(CardRuntimeException.java:46)
at javacard.security.CryptoException.<init>(DashoA10*..:25)
at com.sun.javacard.javax.smartcard.rmiclient.CardObjectFactory.throwIt(Unknown Source)
at com.sun.javacard.javax.smartcard.rmiclient.CardObjectFactory.throwException(Unknown Source)
at com.sun.javacard.javax.smartcard.rmiclient.CardObjectFactory.getObject(Unknown Source)
at com.sun.javacard.rmiclientlib.JCRemoteRefImpl.parseAPDU(Unknown Source)
at com.sun.javacard.rmiclientlib.JCRemoteRefImpl.invoke(Unknown Source)
at sid2.CompteurImpl_Stub.initialiser(Unknown Source)
at sid2.ClientRmi.main(ClientRmi.java:36)

以下是我的JCard applet的代码:

package sid2;

import java.rmi.RemoteException;
import javacard.framework.UserException;
import javacard.framework.service.CardRemoteObject;
import javacard.security.*;
import javacardx.crypto.Cipher;

public class CompteurImpl extends CardRemoteObject implements ICompteur {

    private byte compteur = 120;
    RSAPrivateKey rsa_PrivateKey;
    RSAPublicKey rsa_PublicKey;
    KeyPair rsa_KeyPair;
    Cipher cipherRSA;

    public void setPub(byte[] expo, byte[] mod) {
        rsa_PublicKey.setExponent(expo, (short) 0, (short) expo.length);
        rsa_PublicKey.setModulus(mod, (short) 0, (short) mod.length);
    }

    public byte[] getPub() {
        byte[] ret = null;
        rsa_PublicKey.getModulus(ret, (short) 0);
        rsa_PublicKey.getExponent(ret, (short) (ret.length + 1));

        return ret;
    }

    public void initialiser(byte v) throws RemoteException, UserException {
        rsa_KeyPair = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048);
        rsa_KeyPair.genKeyPair();
        rsa_PublicKey = (RSAPublicKey) rsa_KeyPair.getPublic();
        rsa_PrivateKey = (RSAPrivateKey) rsa_KeyPair.getPrivate();

        compteur = v;
    }
}

有谁可以指出我在这里做错了什么?

PS:我已经尝试了基本的东西,它工作得很好,就像在Jcard上有一个变量并递增它,得到它并设置它。

1 个答案:

答案 0 :(得分:2)

根据JCDK User's Guide (for JC 2.2.2),CREF(C语言RE)实现支持以下alogirthms:

  
      
  • 112-,128-,160-,192-bit ECC
  •   
  • 512位RSA
  •   

因此,行

rsa_KeyPair = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048);

在CREF中执行时应抛出CryptoException.NO_SUCH_ALGORITHM(因为CREF不支持2048位RSA)。

除了这个错误,这可能是你得到的异常的原因,你的代码至少还有一个问题:

byte[] ret = null;
rsa_PublicKey.getModulus(ret, (short) 0);
rsa_PublicKey.getExponent(ret, (short) (ret.length + 1));

这里将缓冲区ret初始化为null,然后尝试将模数和指数填充到缓冲区中。这两个方法(getModulus()getExponent())不会为您创建缓冲区。相反,您需要创建一个适当大小的缓冲区第一个

byte[] buffer = new byte[expected_length];  // Note that you certainly do not want to allocate that buffer within your getPub method!

然后你可以将模数和指数填充到缓冲区中:

byte modLen = rsa_PublicKey.getModulus(buffer, (short) 0);
byte expLen = rsa_PublicKey.getExponent(buffer, (short) modLen);