Java Signature.verify导致SignatureException:签名编码错误由IOException引起:序列标记错误

首先,这不是一个重复的问题,因为大多数人在从缺少“— BEGIN RSA CERTIFICATE —”行的证书创建公钥时报告此exception。

我要做的事情的要点是1.使用SHA1withRSA算法在JCOP智能卡上签名50Byte消息(RSA密钥为1024位)。 2.将签名从智能卡导出到服务器。 3.validation服务器上的签名。

智能卡上的代码片段用于创建签名。 关键点是我在Java Card中使用算法Signature.ALG_RSA_SHA_PKCS1来创建签名。

private void setcustccid(APDU apdu) { byte[] buffer = apdu.getBuffer(); if (buffer[ISO7816.OFFSET_LC] != (byte)24) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } else { short bytesLeft = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF); short readCount = apdu.setIncomingAndReceive(); if (readCount < bytesLeft) { ISOException.throwIt(ISO7816.SW_BYTES_REMAINING_00); } try { Signature signature = Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1, false); signature.init(privKey, Signature.MODE_SIGN); Util.arrayCopy(buffer, (short)buffer[ISO7816.OFFSET_CDATA], tempStorage, (short) 0, (byte)24); Util.arrayCopy(transactionHistory, (short)0, tempStorage, (short)24, (byte)30); } catch (Exception ex) { ISOException.throwIt(ISO7816.SW_BYTES_REMAINING_00); } signature.sign(tempStorage, (short)0, (short)50, finalEncryptedMsg, (short)0); } } 

服务器端的代码片段试图validation从抛出exception的Java智能卡导出的签名。 这里的关键点是我在服务器端使用Signature.getInstance(“SHA1withRSA”)。 我正在对已签名的消息进行Cipher解密,以确认生成的公钥是否正常工作。

 modulusString = new BigInteger(1, rsaModulus); exponentString = new BigInteger(1, rsaExponent); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulusString, exponentString); KeyFactory factor = KeyFactory.getInstance("RSA"); PublicKey publicKey = (RSAPublicKey) factor.generatePublic(keySpec); rsaCipher = Cipher.getInstance("RSA"); rsaCipher.init(Cipher.DECRYPT_MODE, publicKey); signature = Signature.getInstance("SHA1withRSA"); signature.initVerify(publicKey); signature.update(resultBytes); signature.verify(finalEncryptedMsg); tempStorage = rsaCipher.doFinal(finalEncryptedMsg); System.out.println("Decrypted Length = " + tempStorage.length); 

signature.verify()发生exception。 另一个线程引用了同样的exception,但解决方案是在Signature.getInstance()中添加Bouncy Castle作为Provider。 不确定为什么需要Bouncy Castle来validation签名。

任何帮助将不胜感激。 如果您需要更多代码来确定问题,请告诉我们。

 java.security.SignatureException: Signature encoding error at sun.security.rsa.RSASignature.engineVerify(Unknown Source) at java.security.Signature$Delegate.engineVerify(Unknown Source) at java.security.Signature.verify(Unknown Source) at com.mse.reader.SmartCardReader.main(SmartCardReader.java:234) Caused by: java.io.IOException: Sequence tag error at sun.security.util.DerInputStream.getSequence(Unknown Source) at sun.security.rsa.RSASignature.decodeSignature(Unknown Source) ... 4 more 

这是加密消息和解密消息。 (Base4.encodeBase64)

加密长度= 128

 JpypH/vKYR4RLjQA4frCab5WljnAoWgNiGUb0k+DCmh8gdWbOtpR/XUec2rW96Nr1k7czNTb2s/2WQDGXe05a3JjNrlErrfijhdWvn9flIzR/5uPrS3VJw+ALESl8NWqR5HF3AgArE6uYIW87EtSjO0iPJTO2N0cITtLghdUSBs= 

解密长度= 50

 gCUAABgAAAAAO5rJkAAAAAAAvGFOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 

您已将智能卡提供程序移到Java SE上的其他提供程序之前,并且出于某种原因,它还尝试validationRSA签名,而不是仅将其用于RSA私钥操作。

有几种方法可以解决这个问题:

  1. 如果您使用相同的签名实例进行validation,则使用不同的签名实例进行validation
  2. 如果这不能解决您的问题,请尝试查看是否可以将智能卡提供程序放在Security类的提供程序列表中(请查看JCA文档 ,了解如何执行此操作)
  3. 否则只需使用Signature类提供正确的提供程序,我建议指定"SunRsaSign" (您可能希望使此字符串可配置)
  4. com.mse背后的公司解释,他们应该正确实施延迟的提供商选择 ,而不是吞噬用于其硬件设备的软件公钥

请注意,谈论“服务器端”非常混乱,因为智能卡充当服务器。 “终端方”和“卡方”将更加清晰。