Java 当指数超过 10 个字节时,卡片 setExponent() 方法失败
Java Card setExponent() method fails when exponent has more than 10 bytes
我正在尝试使用 RSA CryptoSystem 中的构建在 Java 卡上实现 modPow
功能。该代码看似微不足道,但我已发布实施。
到目前为止我的代码:
Cipher m_encryptCipherRSA = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false); // create the cipher
RSAPublicKey m_rsaPublicKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC,KeyBuilder.LENGTH_RSA_1024,false); // create the public key
m_random = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
m_random.generateData(temp1, (short)0, MODULUS_LENGTH);
m_rsaPublicKey.setModulus(temp1,(short)0, MODULUS_LENGTH); //generate modulus
m_random.generateData(temp1,(short)0, (short) EXPONENT_LENGTH);
m_rsaPublicKey.setExponent(temp1,(short)0, (short)EXPONENT_LENGTH);
如果 EXPONENT_LENGTH
不超过 10 个 bytes.The Java 我的卡限制了 public 指数的维数,鳕鱼似乎工作正常。但是,我的项目基于高达 128
字节 long.Is 的数字,有没有一种方法可以根据此硬件限制创建通用 modpow
函数?有没有另一种方法可以实现仍然可行的幂指数。
我设法通过使用私有指数(这似乎不受 RSA 密码系统的约束)解决了这个问题。下面是工作代码。
public byte[] modPow(byte[] x,short xOffset,short xLength,byte[] y,short yOffset,short yLength)
{
Util.arrayCopy(y, yOffset, tempBuffer, (short)(Configuration.TEMP_OFFSET_EXPONENT+4), yLength);
Util.arrayFillNonAtomic(tempBuffer, Configuration.TEMP_OFFSET_EXPONENT, (byte)4,(byte)0x00);
mRsaPrivateKeyModPow.setExponent(tempBuffer,Configuration.TEMP_OFFSET_EXPONENT, (short)(yLength+4));
mRsaCipherModPow.init(mRsaPrivateKeyModPow, Cipher.MODE_DECRYPT);
Util.arrayCopy(x,xOffset,tempBuffer, Configuration.TEMP_OFFSET_RSA, Configuration.LENGTH_RSAOBJECT_MODULUS);
mRsaCipherModPow.doFinal(tempBuffer,Configuration.TEMP_OFFSET_RSA, (short) (Configuration.LENGTH_RSAOBJECT_MODULUS), tempBuffer,Configuration.TEMP_OFFSET_RSA);
mRsaPrivateKeyModPow.clearKey();
return tempBuffer;
}
好吧,我尝试了 RSAPublicKey
和 RSAPrivateKey
两张不同的卡,都工作正常:
package soqPack;
import javacard.framework.*;
import javacard.security.KeyBuilder;
import javacard.security.RSAPrivateKey;
import javacard.security.RSAPublicKey;
import javacard.security.RandomData;
import javacardx.biometry.BioBuilder;
import javacardx.crypto.Cipher;
public class modPowtest extends Applet {
//Definition Of INS in APDU command
public static final byte INS_MOD_POW = (byte) 0x00;
//Switch cases to choose RSA Public key or RSA Private key for ModPow()
//P1 in APDU command.
public static final byte USE_PUB_KEY = (byte) 0x00;
public static final byte USE_PRI_KEY = (byte) 0x01;
//Required objects
byte[] tempMem;
Cipher myCipher;
RSAPrivateKey rsaPriKey;
RSAPublicKey rsaPubKey;
RandomData random;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new modPowtest();
}
protected modPowtest() {
myCipher = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);
rsaPriKey = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_1024, false);
rsaPubKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_1024, false);
tempMem = JCSystem.makeTransientByteArray((short) 0x80, JCSystem.CLEAR_ON_DESELECT);
random = RandomData.getInstance(RandomData.ALG_PSEUDO_RANDOM);
register();
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
switch (buffer[ISO7816.OFFSET_INS]) {
case INS_MOD_POW:
modPow(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
public void modPow(APDU apdu) {
byte[] buffer = apdu.getBuffer();
switch (buffer[ISO7816.OFFSET_P1]) {
case USE_PUB_KEY:
random.generateData(tempMem, (short) 0x00, (short) 0x80);
rsaPubKey.setModulus(tempMem, (short) 0x00, (short) 0x80);
random.generateData(tempMem, (short) 0x00, (short) 0x03);
rsaPubKey.setExponent(tempMem, (short) 0x00, (short) 0x03);
break;
case USE_PRI_KEY:
random.generateData(tempMem, (short) 0x00, (short) 0x80);
rsaPriKey.setModulus(tempMem, (short) 0x00, (short) 0x80);
random.generateData(tempMem, (short) 0x00, (short) 0x03);
rsaPriKey.setExponent(tempMem, (short) 0x00, (short) 0x03);
break;
default:
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
}
}
工作如下:
Download Cap begin...
Download Cap successful.
Install Applet begin...
Install Applet successful.
Select Applet begin...
Select Applet successful.
Send: 00 00 00 00 00
Recv: 90 00
Send: 00 00 01 00 00
Recv: 90 00
更新:(与评论中的新问题和 相关):
我也在 setModulus
和 setExponent
方法之前将 tempMem[0]
的值更改为 0x69
,它仍然可以正常工作。
我正在尝试使用 RSA CryptoSystem 中的构建在 Java 卡上实现 modPow
功能。该代码看似微不足道,但我已发布实施。
到目前为止我的代码:
Cipher m_encryptCipherRSA = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false); // create the cipher
RSAPublicKey m_rsaPublicKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC,KeyBuilder.LENGTH_RSA_1024,false); // create the public key
m_random = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
m_random.generateData(temp1, (short)0, MODULUS_LENGTH);
m_rsaPublicKey.setModulus(temp1,(short)0, MODULUS_LENGTH); //generate modulus
m_random.generateData(temp1,(short)0, (short) EXPONENT_LENGTH);
m_rsaPublicKey.setExponent(temp1,(short)0, (short)EXPONENT_LENGTH);
如果 EXPONENT_LENGTH
不超过 10 个 bytes.The Java 我的卡限制了 public 指数的维数,鳕鱼似乎工作正常。但是,我的项目基于高达 128
字节 long.Is 的数字,有没有一种方法可以根据此硬件限制创建通用 modpow
函数?有没有另一种方法可以实现仍然可行的幂指数。
我设法通过使用私有指数(这似乎不受 RSA 密码系统的约束)解决了这个问题。下面是工作代码。
public byte[] modPow(byte[] x,short xOffset,short xLength,byte[] y,short yOffset,short yLength)
{
Util.arrayCopy(y, yOffset, tempBuffer, (short)(Configuration.TEMP_OFFSET_EXPONENT+4), yLength);
Util.arrayFillNonAtomic(tempBuffer, Configuration.TEMP_OFFSET_EXPONENT, (byte)4,(byte)0x00);
mRsaPrivateKeyModPow.setExponent(tempBuffer,Configuration.TEMP_OFFSET_EXPONENT, (short)(yLength+4));
mRsaCipherModPow.init(mRsaPrivateKeyModPow, Cipher.MODE_DECRYPT);
Util.arrayCopy(x,xOffset,tempBuffer, Configuration.TEMP_OFFSET_RSA, Configuration.LENGTH_RSAOBJECT_MODULUS);
mRsaCipherModPow.doFinal(tempBuffer,Configuration.TEMP_OFFSET_RSA, (short) (Configuration.LENGTH_RSAOBJECT_MODULUS), tempBuffer,Configuration.TEMP_OFFSET_RSA);
mRsaPrivateKeyModPow.clearKey();
return tempBuffer;
}
好吧,我尝试了 RSAPublicKey
和 RSAPrivateKey
两张不同的卡,都工作正常:
package soqPack;
import javacard.framework.*;
import javacard.security.KeyBuilder;
import javacard.security.RSAPrivateKey;
import javacard.security.RSAPublicKey;
import javacard.security.RandomData;
import javacardx.biometry.BioBuilder;
import javacardx.crypto.Cipher;
public class modPowtest extends Applet {
//Definition Of INS in APDU command
public static final byte INS_MOD_POW = (byte) 0x00;
//Switch cases to choose RSA Public key or RSA Private key for ModPow()
//P1 in APDU command.
public static final byte USE_PUB_KEY = (byte) 0x00;
public static final byte USE_PRI_KEY = (byte) 0x01;
//Required objects
byte[] tempMem;
Cipher myCipher;
RSAPrivateKey rsaPriKey;
RSAPublicKey rsaPubKey;
RandomData random;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new modPowtest();
}
protected modPowtest() {
myCipher = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);
rsaPriKey = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_1024, false);
rsaPubKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_1024, false);
tempMem = JCSystem.makeTransientByteArray((short) 0x80, JCSystem.CLEAR_ON_DESELECT);
random = RandomData.getInstance(RandomData.ALG_PSEUDO_RANDOM);
register();
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
switch (buffer[ISO7816.OFFSET_INS]) {
case INS_MOD_POW:
modPow(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
public void modPow(APDU apdu) {
byte[] buffer = apdu.getBuffer();
switch (buffer[ISO7816.OFFSET_P1]) {
case USE_PUB_KEY:
random.generateData(tempMem, (short) 0x00, (short) 0x80);
rsaPubKey.setModulus(tempMem, (short) 0x00, (short) 0x80);
random.generateData(tempMem, (short) 0x00, (short) 0x03);
rsaPubKey.setExponent(tempMem, (short) 0x00, (short) 0x03);
break;
case USE_PRI_KEY:
random.generateData(tempMem, (short) 0x00, (short) 0x80);
rsaPriKey.setModulus(tempMem, (short) 0x00, (short) 0x80);
random.generateData(tempMem, (short) 0x00, (short) 0x03);
rsaPriKey.setExponent(tempMem, (short) 0x00, (short) 0x03);
break;
default:
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
}
}
工作如下:
Download Cap begin...
Download Cap successful.
Install Applet begin...
Install Applet successful.
Select Applet begin...
Select Applet successful.
Send: 00 00 00 00 00
Recv: 90 00
Send: 00 00 01 00 00
Recv: 90 00
更新:(与评论中的新问题和
我也在 setModulus
和 setExponent
方法之前将 tempMem[0]
的值更改为 0x69
,它仍然可以正常工作。