I generated a KeyPair like this:
ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256k1");
KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
generator.initialize(ecSpec, new SecureRandom());
KeyPair kp = generator.generateKeyPair();
Then I generate Strings from the KeyPair:
String privateKeyString = Base64.getEncoder().encodeToString(kp.getPrivate().getEncoded();
So my first Question is how can I generate a PrivateKey object from privateKeyString and my second question is how can I generate a PublicKey / KeyPair from the PrivateKey object?
Related
Is it possible to take a public key that I have generated, convert it into a string, reverse the process and use it as a key again?
generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048);
KeyPair keyPair = generator.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Then convert this to a string:
String public = someMethod(publicKey)
and then Reverse it at a later time:
RSAPublicKey newPublicKey = someMethod(public)
You can convert the Public Key to a String as follows.
String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
Then that String can be converted back to a public key as follows.
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey2 = keyFactory.generatePublic(spec);
I've used the following code to convert the public and private key to a string
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048);
KeyPair keyPair = keyPairGen.genKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String publicK = Base64.encodeBase64String(publicKey.getEncoded());
String privateK = Base64.encodeBase64String(privateKey.getEncoded());
Now I'm trying to convert it back to public ad private key
PublicKey publicDecoded = Base64.decodeBase64(publicK);
I'm getting error of cannot convert from byte[] to public key. So I tried like this
PublicKey publicDecoded = new SecretKeySpec(Base64.decodeBase64(publicK),"RSA");
This leads to error like below
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: Neither a public nor a private key
Looks like I'm doing wrong key conversion here. Any help would be appreciated.
I don't think you can use the SecretKeySpec with RSA.
This should do:
byte[] publicBytes = Base64.decodeBase64(publicK);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(keySpec);
And to decode the private use PKCS8EncodedKeySpec
I am trying to use [Java JWT] library(https://github.com/auth0/java-jwt) to generate JWT and I require to make instances of private key and public key i.e. RSAPrivateKey and RSAPublicKey.
//RSA
RSAPublicKey publicKey = //Get the key instance
RSAPrivateKey privateKey = //Get the key instance
Algorithm algorithmRS = Algorithm.RSA256(publicKey, privateKey);
How do I create the instances of RSAPrivateKey and RSAPublicKey?
I have created .pem files using OpenSSL (if that helps) but I am not able to use that too.
First create the KeyPairGenerator to create the KeyPairs.
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
This will give you a KeyPairGenerator using RSA. Next you initialize the generator with the amount of bytes you want it to use and then create the KeyPair.
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
Get the PublicKey and PrivateKey from the KeyPair kp using their Getters and than because RsaPublicKey is just a a SubClass of Key and we made these keys with RSA we can safely cast the PublicKey and PrivateKey classes to RSAPublicKey and RSAPrivateKey
RSAPublicKey rPubKey = (RSAPublicKey) kp.getPublic();
RSAPrivateKey rPriKey = (RSAPrivateKey) kp.getPrivate();
I am trying to generate shared secret using EC named curve and finding mismatch in client vs server shared secret.
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
// Client
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");
ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec(ecCurveName);
kpg.initialize(ecGenParameterSpec, new SecureRandom());
ECPublicKey ephemeralPublicKey = (ECPublicKey) kpg.generateKeyPair().getPublic();
ECPrivateKey clientEphemeralPrivateKey =(ECPrivateKey) kpg.generateKeyPair().getPrivate();
BigInteger pointx = ephemeralPublicKey.getW().getAffineX();
BigInteger pointy = ephemeralPublicKey.getW().getAffineY();
String eCClientEphemeralPublicKeyString = ("04"+pointx.toString(16)+pointy.toString(16)).toUpperCase();
byte[] remoteECCPkBytes = DatatypeConverter.parseBase64Binary(remoteECCPkBase64);
KeyFactory keyFactory= KeyFactory.getInstance("EC","BC");
X509EncodedKeySpec pkSpec = new X509EncodedKeySpec(remoteECCPkBytes);
PublicKey serverECCPublicKey = keyFactory.generatePublic(pkSpec);
KeyAgreement ka = KeyAgreement.getInstance("ECDH","BC");
ka.init(clientEphemeralPrivateKey);
ka.doPhase(serverECCPublicKey, true);
SecretKey agreedKey = ka.generateSecret("AES[256]");
byte[] sharedSecret = agreedKey.getEncoded();
// Server
String clientEphemeralPKBase64 = java.util.Base64.getEncoder().encodeToString(new BigInteger(eCClientEphemeralPublicKeyString, 16).toByteArray());
byte[] clientECPublicKeybytes = DatatypeConverter.parseBase64Binary(clientEphemeralPKBase64);
ECParameterSpec ecParameterSpec = ECNamedCurveTable.getParameterSpec(ecCurveName);
ECCurve curve = ecParameterSpec.getCurve();
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(curve.decodePoint(clientECPublicKeybytes), ecParameterSpec);
KeyFactory kf = KeyFactory.getInstance("EC","BC");
ECPublicKey ecClientPublicKey = (ECPublicKey)kf.generatePublic(pubKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec( Base64.decodeBase64(serverprivateKeyBase64));
PrivateKey ecServerPrivateKey = kf.generatePrivate(privateKeySpec);
KeyAgreement ka = KeyAgreement.getInstance("ECDH","BC");
ka.init(ecServerPrivateKey);
ka.doPhase(ecClientPublicKey, true);
SecretKey agreedKey = ka.generateSecret("AES[256]");
byte[] sharedSecret = agreedKey.getEncoded();
This is of course deadly:
ECPublicKey ephemeralPublicKey = (ECPublicKey) kpg.generateKeyPair().getPublic();
ECPrivateKey clientEphemeralPrivateKey =(ECPrivateKey) kpg.generateKeyPair().getPrivate();
If you call generateKeyPair twice your public and private key will not be part of the same key pair.
You need to create two key pairs, one for the server, one for the client and then communicate the public keys. Creating a public key and immediately tossing away the private key cannot be useful, other than to retrieve the domain parameters in a roundabout way.
Instead you should do:
KeyPair clientEphemeralKeyPair = kpg.generateKeyPair();
ECPublicKey clientEphemeralPublicKey = (ECPublicKey) clientEphemeralKeyPair.getPublic();
ECPrivateKey clientEphemeralPrivateKey = (ECPrivateKey) clientEphemeralKeyPair.getPrivate();
Hi all I get the public key as follows
OpenSSLRSAPublicKey{modulus=e6f4b594e1757261a98abe478f47b941cf8339933accc57d73d18bb8da906cf628da1949fb71c51f1635d93067ca2993599965f42d26237f63c1bc333de779051c36805f00ab5698a78e5616a7a7b0df487ba0fb3a89592780984562b96387443774331358a5920815bba2e24ad6c6c4ba6c7f52384847b4feea20190acdef000f6ee078352c0e0764e51dab25037d3d9c819a9be9ea240260ca2217ea4b446caf05d14318941a844ee82f567382c9fad8b959481c27785cdf6cb22ecf80f51bddc9f1c918d56b9bdd80ba4e766209069d0cf2012c0f15dbe4a8b5c2588a0ce295c2e90d44a52190289ab2fdceb22feffdadf623cab33e6a2e98be662cd5fecb,publicExponent=10001}
by using the bellow code
KeyPairGenerator kpg;
KeyPair kp;
PublicKey publicKey;
kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
kp = kpg.genKeyPair();
publicKey = kp.getPublic();
now i want to get the modulus and publicExponent from this.
Can any one suggest please...?
You have to cast the PublicKey to an RSAPublicKey, e.g.
RSAPublicKey rsaPub = (RSAPublicKey)(kp.getPublic());
BigInteger modulus = rsaPub.getModulus();
BigInteger publicExponent = rsaPub getPublicExponent()