【问题标题】:JavaCard RSA Cipher DoFinal ExceptionJavaCard RSA 密码 DoFinal 异常
【发布时间】:2017-03-10 03:13:33
【问题描述】:

我有这段代码可以用 rsa 加密数据:

private static RSAPrivateKey smartcard_rsa_private = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_512, false);
private static RSAPublicKey smartcard_rsa_public = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_512, false);
private static Cipher cipher = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false);

KeyPair kp = new KeyPair(smartcard_rsa_public,smartcard_rsa_private);
kp.genKeyPair();
smartcard_rsa_private=(RSAPrivateKey)kp.getPrivate();
smartcard_rsa_public=(RSAPublicKey)kp.getPublic();
byte[] buffer = apdu.getBuffer();
cipher.init(smartcard_rsa_public, Cipher.MODE_ENCRYPT);
cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, (short) apdu.setIncomingAndReceive(), buffer, (short)0);

我发送以下 APDU:

byte[] data = new byte [64];
new CommandAPDU(0x80, 0x01, 0x00, 0xff, data);

我得到一个错误代码 5,而 doFinal 应该是以下之一:

CryptoException.ILLEGAL_USE 如果满足以下条件之一:

  • 此密码算法不填充消息并且消息不 块对齐。
  • 此密码算法不填充消息并且不 输入数据已在 inBuff 或通过 update() 方法提供。
  • 不支持输入消息长度或消息值为 大于或等于模数。
  • 解密的数据不受适当的填充字节限制。

【问题讨论】:

  • 您能告诉我们您发送的 APDU 吗?看起来像填充问题。
  • @vojta 我更新了问题

标签: java encryption rsa javacard


【解决方案1】:

您的明文不是块对齐的,因为您的输入数据的长度为 64,但具有 512 位公钥的单个 RSA 明文块的长度为 53 字节。

对于 n 位 RSA 密钥,直接加密适用于最多 n/8 - 11 字节的任意二进制消息(前提是 n 可以被 8 整除,当然这通常是)。

真正的问题是为什么要使用 RSA 进行加密而根本没有任何填充机制。没有理由,真的。请改用ALG_RSA_PKCS1

如果您需要加密长数据,请使用 AES 对其进行加密,并将使用 RSA 加密的 AES 密钥与消息一起共享。非对称加密非常慢。

【讨论】:

  • 速度非常慢可能是您只想使用 RSA 加密对称加密的 随机 密钥而不是加密实际数据的最不重要的原因...
  • @MichaelRoland 如果您有任何想法,请改进我的答案。我认为速度是最重要的原因...您还知道哪些其他原因?
  • 参见例如crypto.stackexchange.com/a/126/25798(TL;密文大小的 DR 开销和正确的块链接)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
  • 2019-04-26
  • 1970-01-01
相关资源
最近更新 更多