固定长度64字节EC P-256使用JCE签名

我需要一个固定长度的64字节ECDSA签名和NIST P-256曲线。

该实现有使用JCE。

以下代码示例可以生成签名并进行validation。

Provider provSign = new SunEC(); Provider provVerify = new SunEC(); // generate EC key KeyPairGenerator kg = KeyPairGenerator.getInstance("EC", provSign); ECGenParameterSpec ecParam = new ECGenParameterSpec("secp256r1"); kg.initialize(ecParam); KeyPair keyPair = kg.generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); try { // export public key KeyFactory kf = KeyFactory.getInstance("EC", provSign); ECPublicKeySpec publicKeySpec = kf.getKeySpec(keyPair.getPublic(), ECPublicKeySpec.class); // import public key into other provider kf = KeyFactory.getInstance("EC", provVerify); publicKey = (PublicKey)kf.generatePublic(publicKeySpec); } catch (InvalidKeySpecException ex) { ex.printStackTrace(); } // do test Signature sig = Signature.getInstance("SHA256withECDSA", provSign); Signature ver = Signature.getInstance("SHA256withECDSA", provVerify); byte[] data = new byte[64]; // sign sig.initSign(privateKey); sig.update(data); byte [] sign = sig.sign(); // Working Signature verification ver.initVerify(publicKey); ver.update(data); if (ver.verify(sign) == false) { throw new Exception("Signature Verification failed"); } 

问题是标志以某种方式编码(我认为是DER格式),长度在70到72字节之间,但我需要64字节(未编码/原始)签名。

我尝试过:转换为固定长度64字节签名

  DerInputStream derInputStream = new DerInputStream(sign); DerValue[] values = derInputStream.getSequence(2); byte[] random = values[0].getPositiveBigInteger().toByteArray(); byte[] signature = values[1].getPositiveBigInteger().toByteArray(); // r and s each occupy half the array // Remove padding bytes byte[] tokenSignature = new byte[64]; System.arraycopy(random, random.length > 32 ? 1 : 0, tokenSignature, random.length  32 ? 32 : random.length); System.arraycopy(signature, signature.length > 32 ? 1 : 0, tokenSignature, signature.length  32 ? 32 : signature.length); System.out.println("Full Signature length: "+tokenSignature.length+" r length: "+random.length+" s length"+signature.length); 

如何立即检查64字节tokenSignature ??? 我不知道如何将64字节tokenSignature转换回正确的格式

  ver.initVerify(publicKey); ver.update(data); if (ver.verify(???) == false) { throw new Exception("Signature Verification failed"); } 

我已经使用BouncyCastle ECDSASigner完成了64 Byte签名validation。 但是我不能使用ECDSASigner,因为它没有扩展SignatureSpi,因此不能使用JCE complient加密服务器。

感谢@MaartenBodewes,我现在开始工作了

 //How to Check Signature byte[] r = Arrays.copyOfRange(tokenSignature, 0,tokenSignature.length/2); byte[] s = Arrays.copyOfRange(tokenSignature, tokenSignature.length/2,tokenSignature.length); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); DEROutputStream derOutputStream = new DEROutputStream(byteArrayOutputStream); ASN1EncodableVector v=new ASN1EncodableVector(); v.add(new ASN1Integer(new BigInteger(1,r))); v.add(new ASN1Integer(new BigInteger(1,s))); derOutputStream.writeObject(new DERSequence(v)); byte[] derSignature = byteArrayOutputStream.toByteArray(); ver.update(data); if (ver.verify(derSignature) == false) { throw new Exception("Signature Verification failed"); }