繁体   English   中英

APDU命令中的负数

[英]Negative numbers in APDU command

我在写Java Applet。 我需要使用APDU命令将预先生成的RSAPrivateCrtKey上传到applet。

在我的计算机上,我正在生成密钥。 接下来,我在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);

生成缓冲区后,我应该将每个数组元素转换为十六进制,然后使用APDU发送,最后在applet中恢复我的私钥,但是在privateKeyBuffer我们有负数:

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

我应该如何将它们转换为十六进制并保持APDU正确(因为我只知道允许使用正数),或者可能还有另一种方法将按键推入JavaCard?

有任何想法吗?

您可以简单地将字节数组复制到APDU缓冲区并将其发送。 它会工作。

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

您根本不必考虑十六进制值和正/负数! 当发送一个字节= 8位时,根本不处理其数字表示形式或含义。


特别说明:

byte[] privateKeyBuffer = new byte[165]; 通常是个坏主意。 您根本不需要此缓冲区。 您可以将键值直接复制到APDU缓冲区中,以节省一些持久性内存并使Applet更快。


另一个基于亲爱的@亚伯拉罕的评论的注释:

您在Java Card中可能遇到的带有正/负数字的唯一问题是,不幸的是Java Card byte签名 这意味着它的值始终在[-128,127]范围内,尽管人们常常会忘记它:

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

如果您想将byte理解为无符号的(范围[0,255]),则必须将其强制转换为short

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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