我是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上有一个变量并递增它,得到它并设置它。答案 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);