Good day,
There is another third party that need my web application to send them some data in encrypt format. Thus they send me some guide to do so, however, I am not familiar with it, I am trying to google around but looks like I am google wrong way.
The guide is something as follow:
Run openssl command to generate a privatekey:
openssl ecparam -name prime256v1 -genkey -out myprivate.pem
After run this command, I output a priv.pem file, and I saw inside got some key end with '==', which is as follow:
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEILefWfeuZOgnbDlxpwo3uQ2xQXfhXHUPTS+vKzvVZdCToAoGCCqGSM49
AwEHoUQDQgAE4MeQspGRJ1qdpweBfiaT5P84alZdga1f7mSpa5HqXTH58u0ZWJUQ
J7ToU/bUOPITh4FX07AV6wrgFCmwtUenDQ==
-----END EC PRIVATE KEY-----
Second one is run openssl command to generate the public key, and then send them:
openssl ec -in myprivate.pem -pubout -out mypublic.pem
Convert the private key to pkcs8 format:
openssl pkcs8 -topk8 -nocrypt -in myprivate.pem -out mypkcs8.pem
The third party will give me a public key in string format, then ask me to generate a secret key, and provide me some java code as follow:
first is to generate secret key and second one is encrypt:
public static SecretKey generateSharedSecret(PrivateKey privateKey,
PublicKey publicKey) {
try {
KeyAgreement keyAgreement = KeyAgreement.getInstance( "ECDH" );
keyAgreement.init( privateKey );
keyAgreement.doPhase( publicKey, true );
SecretKeySpec key = new SecretKeySpec(
keyAgreement.generateSecret( ), "AES" );
return key;
} catch ( Exception e ) {
// TODO Auto-generated catch block
e.printStackTrace( );
return null;
}
}
public static String encryptString(SecretKey key, String plainText) {
try {
String myIv = "Testing @ IV!";
byte[] iv = myIv.getBytes( "UTF-8" );
IvParameterSpec ivSpec = new IvParameterSpec( iv );
Cipher cipher = Cipher.getInstance( "AES / CBC / PKCS5Padding" );
byte[] plainTextBytes = plainText.getBytes( "UTF-8" );
byte[] cipherText;
cipher.init( Cipher.ENCRYPT_MODE, key, ivSpec );
cipherText = new byte[cipher.getOutputSize( plainTextBytes.length )];
int encryptLength = cipher.update( plainTextBytes, 0,
plainTextBytes.length, cipherText, 0 );
encryptLength += cipher.doFinal( cipherText, encryptLength );
return bytesToHex( cipherText );
} catch ( Exception e ) {
e.printStackTrace( );
return null;
}
}
and also the bytes to hex string method:
public static String bytesToHex(byte[] byteArray) {
StringBuffer hexStringBuffer = new StringBuffer( );
for ( int i = 0; i < byteArray.length; i++ ) {
hexStringBuffer.append( String.format( "%02X", byteArray[ i ] ) );
}
return hexStringBuffer.toString( );
}
I have self gen a private key and also a public key by using openssl command, but the 4th step telling me that they will give me a public key as well, thus I am not understand, which public key should I use.
And also, how can I convert a String into java PrivateKey
and PublicKey
object?
* add on * I try to convert the der file to java PublicKey object, it looks work. Before this, I convert the pem to der using openssl command:
openssl pkey -pubin -in ecpubkey.pem -outform der -out ecpubkey.der
Here is the java code:
File f = new File("/home/my/Desktop/key/ecpubkey.der");
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
KeyFactory fact = KeyFactory.getInstance("EC");
PublicKey theirpub = fact.generatePublic(new X509EncodedKeySpec(keyBytes));
However, I am hitting java.security.spec.InvalidKeySpecException: java.io.IOException: insufficient data
when I try to convert der file to java PrivateKey object, the following is what I did:
openssl ecparam -name prime256v1 -genkey -out priv.pem
openssl pkcs8 -topk8 -nocrypt -in priv.pem -outform der -out priv.der
And the following is my java code:
File f2 = new File("/home/my/Desktop/key/priv.der");
FileInputStream fis2 = new FileInputStream(f2);
DataInputStream dis2 = new DataInputStream(fis2);
byte[] keyBytes2 = new byte[(int) f.length()];
dis2.readFully(keyBytes2);
dis2.close();
KeyFactory fact2 = KeyFactory.getInstance("EC");
PrivateKey pKey = fact2.generatePrivate( new PKCS8EncodedKeySpec(keyBytes2) ); // this line hit insufficient data