ECDSA signature generation using secp256r1 curve and SHA256 algorithm - BouncyCastle
I am trying to generate a signature using ECDSA with secp256r1 (P256) algorithm and SHA256 for message hash. Also I am using the Bouncy Castle libraries. The code is below,
public class MyTest {
/**
* @param args
*/
public static void main(String[] args) {
new MyTest().getSign();
}
void getSign() {
// Get the instance of the Key Generator with "EC" algorithm
try {
KeyPairGenerator g = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec kpgparams = new ECGenParameterSpec("secp256r1");
g.initialize(kpgparams);
KeyPair pair = g.generateKeyPair();
// Instance of signature class with SHA256withECDSA algorithm
Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
ecdsaSign.initSign(pair.getPrivate());
System.out.println("Private Keys is::" + pair.getPrivate());
System.out.println("Public Keys is::" + pair.getPublic());
String msg = "text ecdsa with sha256";//getSHA256(msg)
ecdsaSign.update((msg + pair.getPrivate().toString())
.getBytes("UTF-8"));
byte[] signature = ecdsaSign.sign();
System.out.println("Signature is::"
+ new BigInteger(1, signature).toString(16));
// Validation
ecdsaSign.initVerify(pair.getPublic());
ecdsaSign.update(signature);
if (ecdsaSign.verify(signature))
System.out.println("valid");
else
System.out.println("invalid!!!!");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
Here the key pairs are generated using the KeyPair, but for my requirement I will have a static privateKey and a public key. In addition, signature verification always returns false.
Need help how can I have a static private key and a validation part.
Jackpot - Nothing in your name is a problem!
First off, you probably aren't actually using BouncyCastle. Sun / Oracle Java 7 and 8 now include an EC provider (there were no earlier versions) and the one-arg form getInstance
uses the first available provider, which is usually SunEC, unless you or someone else has changed the provider list.
CHECK SIGNATURE: send the same data as confirmation Signature.update()
when transferring the signature Signature.update()
. Exactly the same, byte for byte. Pass the signature value only up to Signature.verify()
. Putting it PrivateKey.toString()
into data is silly; this value is specific to the executable Java process, so you will need to send it to the receive process (if different, as usual) where it is useless and a waste of space.
USE STATIC KEY: do just that. Create a key pair and save it somewhere, then read it and use it. The simplest secure (password protected) store is the Java KeyStore (JKS) file, but it requires a chain of certificates (possibly bogus), which is a nuisance for the code itself; fortunately, the keytool
c utility -genkeypair
generates a key pair with a bogus self-configuring certificate, and for -keyalg ec -keysize 256
uses the (very popular) secp256r1 curve. Also include -alias name
, of your choice, -keystore filename
any names you like for the bogus certificate and passwords. To use a key pair from a JKS file:
-
use
java.security.KeyStore.getInstance("JKS")
to create store object and pass.load(InputStream,char[])
aFileInputStream
to file and password. -
use
.getKey(String alias,char[] password)
and cast to get the PrivateKey. Use for signing. -
use
.getCertificateChain(String alias)[0].getPublicKey()
to get the PublicKey from the first (only) certificate. Use to check.
source to share