简体   繁体   中英

Negative numbers in APDU command

I am writing Java Applet. I need to upload pre-generated RSAPrivateCrtKey to applet with APDU Command.

In my computer I am generating key. Next I serialize this key in privateKeyBuffer :

keyPair = new KeyPair(KeyPair.ALG_RSA_CRT, KeyBuilder.LENGTH_RSA_512);
keyPair.genKeyPair();
rsaPrivateKey = (RSAPrivateCrtKey) keyPair.getPrivate();

byte[] privateKeyBuffer = new byte[165];

short lengthDP1 = rsaPrivateKey.getDP1(privateKeyBuffer, 0);
offset += lengthDP1;

short lengthDQ1 = rsaPrivateKey.getDQ1(privateKeyBuffer, offset);
offset += lengthDQ1;

short lengthP = rsaPrivateKey.getP(privateKeyBuffer, offset);
offset += lengthP;

short lengthQ = rsaPrivateKey.getQ(privateKeyBuffer, offset);
offset += lengthQ;

short lengthPQ = rsaPrivateKey.getPQ(privateKeyBuffer, offset);

After generating a buffer I should convert each array element to hex and then send with APDU and last in applet restore my private key, but in privateKeyBuffer we have negative numbers :

37,65,-96,-110,38,6,-2,73,-37,28,120,-90... (etc)

How I should convert them to hex and keep APDU correct (because as I know only positive numbers allowed) or may be there another way to push key to JavaCard?

Any ideas?

You can simply copy your byte array to the APDU buffer and send it. It will work.

final byte[] apduBuffer = apdu.getBuffer();
Util.arrayCopyNonAtomic(privateKeyBuffer, (short) 0, apduBuffer, (short) 0, (short) privateKeyBuffer.length);
apdu.setOutgoingAndSend((short) 0, (short) privateKeyBuffer.length);

You do not have to think about hex values and positive/negative numbers at all! When you send a byte = 8 bits, you do not deal with its number representation or meaning at all.


An extra note:

byte[] privateKeyBuffer = new byte[165]; is generally a bad idea. You do not need this buffer at all. You can copy key values directly into the APDU buffer, save some persistent memory and make your applet faster.


Another note based on dear @Abraham's comment:

The only problem with positive/negative numbers you could face in Java Card is the fact that Java Card byte is signed , unfortunately. That means its values are always in range [-128,127], although people often forget about it:

final byte b = getSomeByteValue(); //from APDU buffer, for example
if (b == 0x80) { //always false!
     //this never happens!
}

If you want to understand your byte as unsigned (range [0, 255]), you have to cast it to short this way:

final byte b = getSomeByteValue(); //from APDU buffer, for example
final short unsignedValue = (short) (b & 0xFF);
if (unsignedValue == 0x80) { //correct!
     //can happen
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM