我编写了下面的JavaCard小程序,在卡上生成512
位RSA公钥和私钥对,并通过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 ................
怎么了?
提前致谢。
答案 0 :(得分:2)
您可能会注意到,返回的值不是全零。响应的前3个字节包含指数。您使用getSize()
方法有什么问题。此方法实际返回密钥大小KeyBuilder.LENGTH_RSA_512
,而不是密钥组件的大小。指数的大小是getExponent()
方法的返回值。
您可以通过执行以下操作来检索公共指数的长度:
publicKeySize = ((RSAPublicKey) thePublicKey).getExponent(publicKey, (short) 0);
你可以对私人指数做同样的事情。
仅供参考,RSA指数=' 01 00 01'很常见,所以我相信它是代码的生成指数。