11import java .security .Security ;
22import java .security .SecureRandom ;
3+ import java .security .interfaces .ECPrivateKey ;
4+ import java .security .interfaces .ECPublicKey ;
35import org .bouncycastle .crypto .AsymmetricCipherKeyPair ;
46import org .bouncycastle .crypto .generators .ECKeyPairGenerator ;
57import org .bouncycastle .crypto .params .ECDomainParameters ;
810import org .bouncycastle .crypto .params .ECPublicKeyParameters ;
911import org .bouncycastle .crypto .signers .ECDSASigner ;
1012import org .bouncycastle .jce .provider .BouncyCastleProvider ;
13+ import org .bouncycastle .jce .spec .ECNamedCurveParameterSpec ;
14+ import org .bouncycastle .jce .spec .ECNamedCurveSpec ;
15+ import org .bouncycastle .jce .ECNamedCurveTable ;
1116import org .bouncycastle .asn1 .sec .SECNamedCurves ;
1217import org .bouncycastle .asn1 .x9 .X9ECParameters ;
18+ import org .bouncycastle .math .ec .ECCurve ;
19+ import org .bouncycastle .math .ec .ECPoint ;
1320
1421/**
15- * Example of using Bouncy Castle's low-level API for ECDSA signing and verification over P-256.
22+ * Test Bouncy Castle's low-level ECDSA API
1623 */
1724public class ECDSAP256SignAndVerify {
25+
1826 public static void main (String [] args ) {
1927 // Add Bouncy Castle provider
2028 Security .addProvider (new BouncyCastleProvider ());
2129
2230 try {
23- // Get P-256 curve parameters using BouncyCastle's SECNamedCurves
24- String curveName = "secp256r1" ;
25- X9ECParameters ecParams = SECNamedCurves .getByName (curveName );
26- ECDomainParameters domainParams = new ECDomainParameters (ecParams );
27-
28- // Generate a key pair
29- SecureRandom random = new SecureRandom ();
30- ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator ();
31- ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters (domainParams , random );
32- keyPairGenerator .init (keyGenParams );
33- AsymmetricCipherKeyPair keyPair = keyPairGenerator .generateKeyPair ();
34-
35- ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters ) keyPair .getPrivate ();
36- ECPublicKeyParameters publicKey = (ECPublicKeyParameters ) keyPair .getPublic ();
37-
3831 byte [] message = "Hello, ECDSA P-256 signature!" .getBytes ("UTF-8" );
3932
40- // Sign the message
41- ECDSASigner signer = new ECDSASigner ();
42- signer .init (true , privateKey ); // true for signing
43- // Note: ECDSA typically signs a hash of the message, not the message directly
44- // For simplicity, we're signing the message bytes directly here
45- java .math .BigInteger [] signature = signer .generateSignature (message );
46-
47- System .out .println ("Signature generated!" );
48- System .out .println ("Signature r: " + signature [0 ].toString (16 ));
49- System .out .println ("Signature s: " + signature [1 ].toString (16 ));
50-
51- // Verify the signature
52- ECDSASigner verifier = new ECDSASigner ();
53- verifier .init (false , publicKey ); // false for verification
54- boolean verified = verifier .verifySignature (message , signature [0 ], signature [1 ]);
55-
56- System .out .println ("Signature verified: " + verified );
33+ // Test different key generation methods
34+ signWithKeyPair (generateKeyPair1 (), message );
35+ signWithKeyPair (generateKeyPair2 (), message );
36+ signWithKeyPair (generateKeyPair3 (), message );
5737 } catch (Exception e ) {
5838 e .printStackTrace ();
5939 }
6040 }
41+
42+ /**
43+ * Method 1: Generate key pair with SECNamedCurves
44+ */
45+ private static AsymmetricCipherKeyPair generateKeyPair1 () throws Exception {
46+ // Get P-256 curve parameters using BouncyCastle's SECNamedCurves
47+ String curveName = "secp256r1" ;
48+ X9ECParameters ecParams = SECNamedCurves .getByName (curveName );
49+ ECDomainParameters domainParams = new ECDomainParameters (ecParams );
50+
51+ // Generate a key pair
52+ SecureRandom random = new SecureRandom ();
53+ ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator ();
54+ ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters (domainParams , random );
55+ keyPairGenerator .init (keyGenParams );
56+
57+ return keyPairGenerator .generateKeyPair ();
58+ }
59+
60+ /**
61+ * Method 2: Generate key pair with explicit curve construction
62+ */
63+ private static AsymmetricCipherKeyPair generateKeyPair2 () throws Exception {
64+ // Get the X9.62 parameters and construct domain parameters explicitly
65+ String curveName = "secp256k1" ;
66+ X9ECParameters x9Params = SECNamedCurves .getByName (curveName );
67+ ECCurve curve = x9Params .getCurve ();
68+ ECPoint g = x9Params .getG ();
69+ java .math .BigInteger n = x9Params .getN ();
70+ java .math .BigInteger h = x9Params .getH ();
71+
72+ // Create domain parameters with explicit values
73+ ECDomainParameters domainParams = new ECDomainParameters (curve , g , n , h );
74+
75+ SecureRandom random = new SecureRandom ();
76+ ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator ();
77+ ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters (domainParams , random );
78+ keyPairGenerator .init (keyGenParams );
79+
80+ return keyPairGenerator .generateKeyPair ();
81+ }
82+
83+
84+ /**
85+ * Method 3: Generate key pair using ECNamedCurveTable
86+ */
87+ private static AsymmetricCipherKeyPair generateKeyPair3 () throws Exception {
88+ // Get curve parameters using ECNamedCurveTable
89+ String curveName = "secp384r1" ;
90+ ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable .getParameterSpec (curveName );
91+ ECDomainParameters domainParams = new ECDomainParameters (
92+ ecSpec .getCurve (),
93+ ecSpec .getG (),
94+ ecSpec .getN (),
95+ ecSpec .getH ()
96+ );
97+
98+ SecureRandom random = new SecureRandom ();
99+ ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator ();
100+ ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters (domainParams , random );
101+ keyPairGenerator .init (keyGenParams );
102+
103+ return keyPairGenerator .generateKeyPair ();
104+ }
105+
106+ /**
107+ * Test signing and verification with BouncyCastle low-level key pair
108+ */
109+ private static void signWithKeyPair (AsymmetricCipherKeyPair keyPair , byte [] message ) throws Exception {
110+ ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters ) keyPair .getPrivate ();
111+ ECPublicKeyParameters publicKey = (ECPublicKeyParameters ) keyPair .getPublic ();
112+
113+ // Sign the message
114+ ECDSASigner signer = new ECDSASigner ();
115+ signer .init (true , privateKey ); // true for signing
116+ java .math .BigInteger [] signature = signer .generateSignature (message );
117+
118+ // Verify the signature
119+ ECDSASigner verifier = new ECDSASigner ();
120+ verifier .init (false , publicKey ); // false for verification
121+ boolean verified = verifier .verifySignature (message , signature [0 ], signature [1 ]);
122+ }
61123}
0 commit comments