RSA 密钥对生成器小程序,生成固定的几乎为零的私有和 public 密钥
RSA key pair generator applet, generate fixed almost zero private and public keys
我编写了下面的 JavaCard 小程序来生成 512
位 RSA public 和卡上的私钥对,并通过 APDU 响应将它们传输到外部:
public class CryptoRSA extends Applet {
//Abbreviations
private static final boolean NO_EXTERNAL_ACCESS = false;
//arrays for generated keys in byte. (I know that 64 byte is enough)
byte[] publicKey = new byte[128];
byte[] privateKey = new byte[128];
//Switch case parameters for selecting instruction = INS in apdu command
private static final byte GENERATE_KEY_PAIR = (byte) 0xC0;
//Create object of keys
RSAPrivateKey thePrivateKey = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_512, NO_EXTERNAL_ACCESS);
RSAPublicKey thePublickKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_512, NO_EXTERNAL_ACCESS);
KeyPair theKeyPair = new KeyPair(thePublickKey, thePrivateKey);
public static void install(byte[] bArray, short bOffset, byte bLength) {
new CryptoRSA();
}
protected CryptoRSA() {
register();
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
short privateKeySize = 0;
short publicKeySize = 0;
byte[] publicArray;
byte[] privateArray;
try {
switch (buffer[ISO7816.OFFSET_INS]) {
case GENERATE_KEY_PAIR:
theKeyPair.genKeyPair();
PrivateKey thePrivateKey = theKeyPair.getPrivate();
PublicKey thePublicKey = theKeyPair.getPublic();
publicKeySize = thePublicKey.getSize();
privateKeySize = thePrivateKey.getSize();
//In the first program I used the followin transient arrays,
//... and output was zero always. As I was thought
//... that the origin of my problem is these transient arrays,
//... (I think we cannot copy transient array to APDU buffer, Am I right?)
//... I use above global arrays, but the problem remained
//... as the first program.
// byte[] publicKey = JCSystem.makeTransientByteArray((short) (publicKeySize / 8), JCSystem.CLEAR_ON_DESELECT);
// byte[] privateKey = JCSystem.makeTransientByteArray((short) (privateKeySize / 8), JCSystem.CLEAR_ON_DESELECT);
((RSAPublicKey) thePublicKey).getExponent(publicKey, (short) 0);
((RSAPrivateKey) thePrivateKey).getExponent(privateKey, (short) 0);
Util.arrayCopyNonAtomic(publicKey, (short) 0, buffer, (short) 0, (short) (publicKeySize / 8));
Util.arrayCopyNonAtomic(privateKey, (short) 0, buffer, (short) publicKeySize, (short) (privateKeySize / 8));
apdu.setOutgoingAndSend((short) 0, (short) ((short)(publicKeySize+privateKeySize) / 8));
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
} catch (CryptoException e) {
short r = e.getReason();
ISOException.throwIt(r);
}
}
}
问题是输出是固定的,几乎总是为零:
OpenSC:: opensc-tool.exe -s 00a40400060102030405DD -s 00c00000
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 DD
Received (SW1=0x90, SW2=0x00)
Sending: 00 C0 00 00
Received (SW1=0x90, SW2=0x00):
01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
OpenSC:: opensc-tool.exe -s 00a40400060102030405DD -s 00c00000
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 DD
Received (SW1=0x90, SW2=0x00)
Sending: 00 C0 00 00
Received (SW1=0x90, SW2=0x00):
01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
怎么了?
提前致谢。
您可能会注意到,返回值并非全为零。响应的前 3 个字节包含指数。问题出在您对 getSize()
方法的使用上。此方法实际上 returns 密钥大小 KeyBuilder.LENGTH_RSA_512
而不是密钥组件的大小。指数的大小是getExponent()
方法的返回值。
您可以通过执行以下操作检索 public 指数的长度:
publicKeySize = ((RSAPublicKey) thePublicKey).getExponent(publicKey, (short) 0);
您可以对私有指数执行相同的操作。
仅供参考,RSA 指数 = '01 00 01' 很常见,因此我相信这是您的代码生成的指数。
我编写了下面的 JavaCard 小程序来生成 512
位 RSA public 和卡上的私钥对,并通过 APDU 响应将它们传输到外部:
public class CryptoRSA extends Applet {
//Abbreviations
private static final boolean NO_EXTERNAL_ACCESS = false;
//arrays for generated keys in byte. (I know that 64 byte is enough)
byte[] publicKey = new byte[128];
byte[] privateKey = new byte[128];
//Switch case parameters for selecting instruction = INS in apdu command
private static final byte GENERATE_KEY_PAIR = (byte) 0xC0;
//Create object of keys
RSAPrivateKey thePrivateKey = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_512, NO_EXTERNAL_ACCESS);
RSAPublicKey thePublickKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_512, NO_EXTERNAL_ACCESS);
KeyPair theKeyPair = new KeyPair(thePublickKey, thePrivateKey);
public static void install(byte[] bArray, short bOffset, byte bLength) {
new CryptoRSA();
}
protected CryptoRSA() {
register();
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
short privateKeySize = 0;
short publicKeySize = 0;
byte[] publicArray;
byte[] privateArray;
try {
switch (buffer[ISO7816.OFFSET_INS]) {
case GENERATE_KEY_PAIR:
theKeyPair.genKeyPair();
PrivateKey thePrivateKey = theKeyPair.getPrivate();
PublicKey thePublicKey = theKeyPair.getPublic();
publicKeySize = thePublicKey.getSize();
privateKeySize = thePrivateKey.getSize();
//In the first program I used the followin transient arrays,
//... and output was zero always. As I was thought
//... that the origin of my problem is these transient arrays,
//... (I think we cannot copy transient array to APDU buffer, Am I right?)
//... I use above global arrays, but the problem remained
//... as the first program.
// byte[] publicKey = JCSystem.makeTransientByteArray((short) (publicKeySize / 8), JCSystem.CLEAR_ON_DESELECT);
// byte[] privateKey = JCSystem.makeTransientByteArray((short) (privateKeySize / 8), JCSystem.CLEAR_ON_DESELECT);
((RSAPublicKey) thePublicKey).getExponent(publicKey, (short) 0);
((RSAPrivateKey) thePrivateKey).getExponent(privateKey, (short) 0);
Util.arrayCopyNonAtomic(publicKey, (short) 0, buffer, (short) 0, (short) (publicKeySize / 8));
Util.arrayCopyNonAtomic(privateKey, (short) 0, buffer, (short) publicKeySize, (short) (privateKeySize / 8));
apdu.setOutgoingAndSend((short) 0, (short) ((short)(publicKeySize+privateKeySize) / 8));
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
} catch (CryptoException e) {
short r = e.getReason();
ISOException.throwIt(r);
}
}
}
问题是输出是固定的,几乎总是为零:
OpenSC:: opensc-tool.exe -s 00a40400060102030405DD -s 00c00000
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 DD
Received (SW1=0x90, SW2=0x00)
Sending: 00 C0 00 00
Received (SW1=0x90, SW2=0x00):
01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
OpenSC:: opensc-tool.exe -s 00a40400060102030405DD -s 00c00000
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 DD
Received (SW1=0x90, SW2=0x00)
Sending: 00 C0 00 00
Received (SW1=0x90, SW2=0x00):
01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
怎么了?
提前致谢。
您可能会注意到,返回值并非全为零。响应的前 3 个字节包含指数。问题出在您对 getSize()
方法的使用上。此方法实际上 returns 密钥大小 KeyBuilder.LENGTH_RSA_512
而不是密钥组件的大小。指数的大小是getExponent()
方法的返回值。
您可以通过执行以下操作检索 public 指数的长度:
publicKeySize = ((RSAPublicKey) thePublicKey).getExponent(publicKey, (short) 0);
您可以对私有指数执行相同的操作。
仅供参考,RSA 指数 = '01 00 01' 很常见,因此我相信这是您的代码生成的指数。