1
1
import java .security .Security ;
2
2
import java .security .SecureRandom ;
3
+ import java .security .interfaces .ECPrivateKey ;
4
+ import java .security .interfaces .ECPublicKey ;
3
5
import org .bouncycastle .crypto .AsymmetricCipherKeyPair ;
4
6
import org .bouncycastle .crypto .generators .ECKeyPairGenerator ;
5
7
import org .bouncycastle .crypto .params .ECDomainParameters ;
8
10
import org .bouncycastle .crypto .params .ECPublicKeyParameters ;
9
11
import org .bouncycastle .crypto .signers .ECDSASigner ;
10
12
import 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 ;
11
16
import org .bouncycastle .asn1 .sec .SECNamedCurves ;
12
17
import org .bouncycastle .asn1 .x9 .X9ECParameters ;
18
+ import org .bouncycastle .math .ec .ECCurve ;
19
+ import org .bouncycastle .math .ec .ECPoint ;
13
20
14
21
/**
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
16
23
*/
17
24
public class ECDSAP256SignAndVerify {
25
+
18
26
public static void main (String [] args ) {
19
27
// Add Bouncy Castle provider
20
28
Security .addProvider (new BouncyCastleProvider ());
21
29
22
30
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
-
38
31
byte [] message = "Hello, ECDSA P-256 signature!" .getBytes ("UTF-8" );
39
32
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 );
57
37
} catch (Exception e ) {
58
38
e .printStackTrace ();
59
39
}
60
40
}
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
+ }
61
123
}
0 commit comments