gpt4 book ai didi

Javacard - 签名和验证

转载 作者:行者123 更新时间:2023-11-29 03:07:58 26 4
gpt4 key购买 nike

我正在尝试在卡上签署一条消息并在卡外验证它。

结果总是假的。

我可能获取的模数和指数不正确。有什么想法吗?

Java 小程序代码:

protected MainApplet() {

try {
// CREATE RSA KEYS AND PAIR
m_keyPair = new KeyPair(KeyPair.ALG_RSA_CRT, KeyBuilder.LENGTH_RSA_1024);
// STARTS ON-CARD KEY GENERATION PROCESS
m_keyPair.genKeyPair();

// OBTAIN KEY REFERENCES
m_publicKey = (RSAPublicKey) m_keyPair.getPublic();
m_privateKey = (RSAPrivateCrtKey) m_keyPair.getPrivate();


} catch (CryptoException c) {
//this line will give you the reason of problem
short reason = c.getReason();
ISOException.throwIt(reason); // for check
}

}

.......

    switch (INS) {
case 0x00:
getPublicKeyExp(apdu);
break;
case 0x10:
getPublicKeyMod(apdu);
break;
case 0x21:
signMessage(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}

private void getExponent(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short length = m_publicKey.getExponent(buffer, ISO7816.OFFSET_CDATA);
apdu.setOutgoingAndSend((short) 0, length);
}

private void getModulus(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short length = m_publicKey.getModulus(buffer, ISO7816.OFFSET_CDATA);
apdu.setOutgoingAndSend((short) 0, length);

}

Java 主机代码:

        /*************** EXECUTE COMMAND *************/
byte[] get_exponent = {
(byte) 0x80, // CLA Class
0x00, // INS Instruction
0x00, // P1 Parameter 1
0x00, // P2 Parameter 2
0x00 // LE maximal number of bytes expected in result
};
byte[] get_modulus = {
(byte) 0x80, // CLA Class
0x10, // INS Instruction
0x00, // P1 Parameter 1
0x00, // P2 Parameter 2
0x00 // LE maximal number of bytes expected in result
};

ResponseAPDU resp_modulus = channel.transmit(new CommandAPDU(get_modulus));
System.out.println(resp_modulus.toString());

ResponseAPDU resp_exponent = channel.transmit(new CommandAPDU(get_exponent));
System.out.println(resp_exponent.toString());


byte[] modulus = resp_modulus.getData();
byte[] exponent = resp_exponent.getData();

创建公钥的代码:

    RSAPublicKeySpec keySpec =  new RSAPublicKeySpec(new BigInteger(1, modulus), new BigInteger(1, exponent));

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(keySpec);

验证消息的代码:

byte[] get_signed_message = {
(byte) 0x80, // CLA Class
0x21, // INS Instruction
0x00, // P1 Parameter 1
0x00, // P2 Parameter 2
0x00 // LE maximal number of bytes expected in result
};
ResponseAPDU resp = channel.transmit(new CommandAPDU(get_signed_message));
System.out.println(resp.toString());
byte[] sigToVerify = resp.getData();

Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(publicKey);

sig.update(sigToVerify);

boolean verifies = sig.verify(sigToVerify);

更新:Java 小程序签名方法

byte[] testSig = new byte[256];
byte[] test = {0x01, 0x02, 0x04, 0x05, 0x06, 0x07};
// CREATE SIGNATURE OBJECT
Signature m_sign = Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1, false);
// INIT WITH PRIVATE KEY
m_sign.init(m_privateKey, Signature.MODE_SIGN);

short len = m_sign.sign(test, (short) 0, (short) test.length, testSig, (short) 0);
apdu.setOutgoing();
apdu.setOutgoingLength(len);
apdu.sendBytesLong(testSig, (short) 0, len);

最佳答案

问题出在这两个方法 getExponent()getModulus() 中。您正在将指数模数 存储到buffer 的索引ISO7816.OFFSET_CDATA(索引 5)中,但将其发送到外部来自 buffer 的索引 0

比较正确的方法和错误的方法:

错误:

private void getExponent(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short length = m_publicKey.getExponent(buffer, ISO7816.OFFSET_CDATA);
apdu.setOutgoingAndSend((short) 0, length); // not the valid public exp
}

private void getModulus(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short length = m_publicKey.getModulus(buffer, ISO7816.OFFSET_CDATA);
apdu.setOutgoingAndSend((short) 0, length); // not the valid mod
}

正确 1(赞赏):

private void getExponent(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short length = m_publicKey.getExponent(buffer, (short) 0);
apdu.setOutgoingAndSend((short) 0, length);
}

private void getModulus(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short length = m_publicKey.getModulus(buffer, (short) 0);
apdu.setOutgoingAndSend((short) 0, length);
}

正确 2:

private void getExponent(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short length = m_publicKey.getExponent(buffer, ISO7816.OFFSET_CDATA);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, length);
}

private void getModulus(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short length = m_publicKey.getModulus(buffer, ISO7816.OFFSET_CDATA);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, length);
}

编辑:在您的主机应用程序中,您需要以下内容:

byte[] test = {0x01, 0x02, 0x04, 0x05, 0x06, 0x07}; 
sig.update(test);
boolean verifies = sig.verify(sigToVerify);

要验证签名,您需要

  • 公钥
  • 验证机制(比如 SHA1withRSA)
  • 纯文本(从中生成签名)
  • 签名

关于Javacard - 签名和验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31102322/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com