6161import org .apache .commons .io .FileUtils ;
6262import org .apache .commons .logging .Log ;
6363import org .apache .commons .logging .LogFactory ;
64+ import org .bouncycastle .asn1 .ASN1Encodable ;
65+ import org .bouncycastle .asn1 .ASN1InputStream ;
6466import org .bouncycastle .asn1 .ASN1Integer ;
67+ import org .bouncycastle .asn1 .ASN1Primitive ;
68+ import org .bouncycastle .asn1 .ASN1Sequence ;
6569import org .bouncycastle .asn1 .DERSequenceGenerator ;
6670import org .bouncycastle .asn1 .x9 .ECNamedCurveTable ;
6771import org .bouncycastle .asn1 .x9 .X9ECParameters ;
6872import org .bouncycastle .crypto .Digest ;
6973import org .bouncycastle .crypto .digests .SHA256Digest ;
7074import org .bouncycastle .crypto .digests .SHA3Digest ;
71- import org .bouncycastle .crypto .params .ECDomainParameters ;
72- import org .bouncycastle .crypto .params .ECPrivateKeyParameters ;
73- import org .bouncycastle .crypto .signers .ECDSASigner ;
7475import org .bouncycastle .jce .provider .BouncyCastleProvider ;
7576import org .bouncycastle .openssl .jcajce .JcaPEMWriter ;
7677import org .bouncycastle .operator .ContentSigner ;
@@ -599,6 +600,42 @@ private KeyPair generateKey(String encryptionName, String curveName) throws Cryp
599600 }
600601 }
601602
603+ /**
604+ * Decodes an ECDSA signature and returns a two element BigInteger array.
605+ *
606+ * @param signature ECDSA signature bytes.
607+ * @return BigInteger array for the signature's r and s values
608+ * @throws Exception
609+ */
610+ private static BigInteger [] decodeECDSASignature (byte [] signature ) throws Exception {
611+ ByteArrayInputStream inStream = new ByteArrayInputStream (signature );
612+ ASN1InputStream asnInputStream = new ASN1InputStream (inStream );
613+ ASN1Primitive asn1 = asnInputStream .readObject ();
614+
615+ BigInteger [] sigs = new BigInteger [2 ];
616+ int count = 0 ;
617+ if (asn1 instanceof ASN1Sequence ) {
618+ ASN1Sequence asn1Sequence = (ASN1Sequence ) asn1 ;
619+ ASN1Encodable [] asn1Encodables = asn1Sequence .toArray ();
620+ for (ASN1Encodable asn1Encodable : asn1Encodables ) {
621+ ASN1Primitive asn1Primitive = asn1Encodable .toASN1Primitive ();
622+ if (asn1Primitive instanceof ASN1Integer ) {
623+ ASN1Integer asn1Integer = (ASN1Integer ) asn1Primitive ;
624+ BigInteger integer = asn1Integer .getValue ();
625+ if (count < 2 ) {
626+ sigs [count ] = integer ;
627+ }
628+ count ++;
629+ }
630+ }
631+ }
632+ if (count != 2 ) {
633+ throw new CryptoException (format ("Invalid ECDSA signature. Expected count of 2 but got: %d. Signature is: %s" , count ,
634+ DatatypeConverter .printHexBinary (signature )));
635+ }
636+ return sigs ;
637+ }
638+
602639
603640 /**
604641 * Sign data with the specified elliptic curve private key.
@@ -610,19 +647,16 @@ private KeyPair generateKey(String encryptionName, String curveName) throws Cryp
610647 */
611648 private byte [] ecdsaSignToBytes (ECPrivateKey privateKey , byte [] data ) throws CryptoException {
612649 try {
613- final byte [] encoded = hash (data );
614-
615650 X9ECParameters params = ECNamedCurveTable .getByName (curveName );
616651 BigInteger curveN = params .getN ();
617652
618- ECDomainParameters ecParams = new ECDomainParameters (params .getCurve (), params .getG (), curveN ,
619- params .getH ());
620-
621- ECDSASigner signer = new ECDSASigner ();
653+ Signature sig = SECURITY_PROVIDER == null ? Signature .getInstance (DEFAULT_SIGNATURE_ALGORITHM ) :
654+ Signature .getInstance (DEFAULT_SIGNATURE_ALGORITHM , SECURITY_PROVIDER );
655+ sig .initSign (privateKey );
656+ sig .update (data );
657+ byte [] signature = sig .sign ();
622658
623- ECPrivateKeyParameters privKey = new ECPrivateKeyParameters (privateKey .getS (), ecParams );
624- signer .init (true , privKey );
625- BigInteger [] sigs = signer .generateSignature (encoded );
659+ BigInteger [] sigs = decodeECDSASignature (signature );
626660
627661 sigs = preventMalleability (sigs , curveN );
628662
0 commit comments