java.security.spec.InvalidKeySpecException and Inappropriate key specification error in java program
15,972
Ciphertext and keys should both consist of random bytes. Neither one of them can be represented 1:1 with a string. Not all bytes may represent valid encodings for a specific character-encoding.
Instead you should use byte arrays directly. If you require actual text, use either hexadecimals or base 64 encoding.
Your code using ciphertext as bytes and a key specified in hexadecimals:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.spec.EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import codec.Hex;
public class Pgm {
public static void main(String[] args) {
try {
KeyPairGenerator dsa = KeyPairGenerator.getInstance("DSA");
SecureRandom random = new SecureRandom();
dsa.initialize(1024, random);
KeyPair keypair = dsa.generateKeyPair();
PrivateKey privateKey = (PrivateKey) keypair.getPrivate();
byte[] key = Hex.decode("000102030405060708090A0B0C0D0E0F");
Key aesKey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
String currentDir = System.getProperty("user.dir");
// encrypt the text
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] abc = privateKey.getEncoded();
byte[] encrypted = cipher.doFinal(abc);
// System.out.println("len="+encrypted.length());
File dir = new File(currentDir);
File private_file = new File(dir, "privatekey.txt");
if (!private_file.exists()) {
private_file.createNewFile();
}
FileOutputStream fileos = new FileOutputStream(private_file);
ObjectOutputStream objectos = new ObjectOutputStream(fileos);
objectos.writeObject(encrypted);
objectos.close();
fileos.close();
File file_private = new File(dir, "privatekey.txt");
FileInputStream fileo = new FileInputStream(file_private);
ObjectInputStream objos = new ObjectInputStream(fileo);
Object obj = objos.readObject();
byte[] encrypted1 = (byte[]) obj;
cipher.init(Cipher.DECRYPT_MODE, aesKey);
byte[] decrypted = cipher.doFinal(encrypted1);
if (Arrays.equals(decrypted, abc))
System.out.println("true");
else
System.out.println("false");
Signature tosign = Signature.getInstance("DSA");
KeyFactory generator = KeyFactory.getInstance("DSA");
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(decrypted);
PrivateKey privatekey1 = generator.generatePrivate(privateKeySpec);
tosign.initSign(privatekey1);
} catch (Exception e) {
System.out.println("failed");
e.printStackTrace();
}
}
}
Author by
user123
Updated on June 04, 2022Comments
-
user123 almost 2 years
As a part of project implementation,I have done: 1. Generete DSA keys 2. Encrypt the private key using AES 3. Save into the file 4. Open the file and read the encrypted private key 5. I tried to convert the read value into primary key format
import java.security.spec.EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.Security; import java.io.File; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.io.*; import java.security.*; import java.util.logging.Level; import java.util.logging.Logger; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; public class Pgm { public static void main(String[] args) { try { KeyPairGenerator dsa = KeyPairGenerator.getInstance("DSA"); SecureRandom random = new SecureRandom(); dsa.initialize(1024, random); KeyPair keypair = dsa.generateKeyPair(); PrivateKey privateKey = (PrivateKey) keypair.getPrivate(); byte[] key = "�u���1�iw&a".getBytes(); Key aesKey = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES"); String currentDir = System.getProperty("user.dir"); // encrypt the text cipher.init(Cipher.ENCRYPT_MODE, aesKey); byte[] abc = privateKey.getEncoded(); byte[] encrypted = cipher.doFinal(abc); // System.out.println("len="+encrypted.length()); File dir = new File(currentDir); File private_file = new File(dir, "privatekey.txt"); if (!private_file.exists()) { private_file.createNewFile(); } FileOutputStream fileos = new FileOutputStream(private_file); ObjectOutputStream objectos = new ObjectOutputStream(fileos); objectos.writeObject(encrypted); objectos.close(); fileos.close(); File file_private = new File(dir, "privatekey.txt"); FileInputStream fileo = new FileInputStream(file_private); ObjectInputStream objos = new ObjectInputStream(fileo); Object obj = objos.readObject(); byte[] encrypted1 = (byte[]) obj; cipher.init(Cipher.DECRYPT_MODE, aesKey); String decrypted = new String(cipher.doFinal(encrypted1)); if (decrypted.equals(new String(abc))) System.out.println("true"); else System.out.println("false"); Signature tosign = Signature.getInstance("DSA"); byte[] val = decrypted.getBytes(); KeyFactory generator = KeyFactory.getInstance("DSA"); EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(val); PrivateKey privatekey1 = generator.generatePrivate(privateKeySpec); tosign.initSign(privatekey1); } catch (Exception e) { System.out.println("failed"); e.printStackTrace(); } } }
While I am trying to execute the above code, it shows the following error!
-
Maarten Bodewes over 9 yearsI've now used the Hex codec from Apache Codec, but you can of course use any encoding. Base 64 encoding is now supported by default in Java 8, but hex isn't yet (at least not in one of the
util
packages). -
user123 over 9 yearsThank you for your reply. Now the code is working. The problem in my code is an unwanted conversion from byte[] to string and back from string to byte[]. 'String decrypted = new String(cipher.doFinal(encrypted1));'