today, I wrote some code to encrypt a String with AES and encrypt the key with RSA. When I try to decrypt the everything, Java gives me a BadPaddingException.
Here is my code:
Test.java:
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Scanner;
public class Test {
private static String publicName = null;
private static String privateName = null;
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Choose an option: \n(1) Decrypt \n(2) Encrypt \n(3) Generate Keypair");
int choice = scanner.nextInt();
if(choice == 1) decrypt();
else if(choice == 2) encrypt();
else if(choice == 3) makeKeypair();
}
private static void makeKeypair() throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the name of your public key: ");
publicName = scanner.nextLine() + ".key";
System.out.println("Enter the name of your private key: ");
privateName = scanner.nextLine() + ".key";
KeyMaker keyMaker = new KeyMaker(publicName, privateName);
keyMaker.generateKeys();
}
public static void encrypt() throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the text you want to encrypt: ");
String toEncrypt = scanner.nextLine();
System.out.println("Enter the name of the public key you want to use: ");
publicName = scanner.nextLine() + ".key";
Encrypter encrypter = new Encrypter(publicName);
Key key = generateKey();
String encryptedWithAES = encryptAES(toEncrypt, key);
String encodedKey = java.util.Base64.getEncoder().encodeToString(key.getEncoded());
String encryptedKey = encrypter.rsaEncrypt(encodedKey);
String finalOutput = encryptedKey + encryptedWithAES;
System.out.println("Enter the name of the file encrypted file which will be created: ");
String fileName = scanner.nextLine();
PrintWriter out = new PrintWriter(fileName + ".txt");
out.println(finalOutput);
out.close();
System.out.println("DONE - saved as: " + fileName + ".txt");
scanner.close();
}
public static void decrypt() throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the name of your encrypted file: ");
String fileName = scanner.nextLine() + ".txt";
String givenInput = null;
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = br.readLine()) != null) {
givenInput = givenInput + line;
}
}
assert givenInput != null;
String encryptedKey = givenInput.substring(0,172);
String encryptedWithAES = givenInput.replace(encryptedKey, "");
System.out.println("Enter the name of your private key: ");
privateName = scanner.nextLine() + ".key";
Decrypter decrypter = new Decrypter(privateName);
String decryptedKey = decrypter.rsaDecrypt(encryptedKey);
byte[] decodedKey = java.util.Base64.getDecoder().decode(decryptedKey);
Key originalKey = new SecretKeySpec(decodedKey, "AES");
String decryptedWithAES = decryptAES(encryptedWithAES, originalKey);
System.out.println(decryptedWithAES);
scanner.close();
}
public static Key generateKey() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom();
kg.init(random);
return kg.generateKey();
}
private static String encryptAES(String message, Key key) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[] stringBytes = message.getBytes();
byte[] raw = cipher.doFinal(stringBytes);
return Base64.encodeBase64String(raw);
}
public static String decryptAES(String encrypted, Key key) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] raw = Base64.decodeBase64(encrypted);
byte[] stringBytes = cipher.doFinal(raw);
return new String(stringBytes, "UTF8");
}
}
KeyMaker.java:
import java.io.FileOutputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class KeyMaker {
String publicName;
String privateName;
public KeyMaker(String publicName, String privateName) {
this.publicName = publicName;
this.privateName = privateName;
}
public void generateKeys() throws Exception{
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();
PrivateKey privateKey = kp.getPrivate();
PublicKey publicKey = kp.getPublic();
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream(publicName);
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
privateKey.getEncoded());
fos = new FileOutputStream(privateName);
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
}
}
Encrypter.java:
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.*;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
public class Encrypter {
String keyFileName;
public Encrypter(String keyFileName) {
this.keyFileName = keyFileName;
}
public String rsaEncrypt(String data) throws Exception {
PublicKey pubKey = readPublicKeyFromFile(keyFileName);
byte[] utf8 = data.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] enc = cipher.doFinal(Base64.encodeBase64(utf8));
return Base64.encodeBase64String(enc);
}
private PublicKey readPublicKeyFromFile(String keyFileName) throws Exception {
File filePublicKey = new File(keyFileName);
FileInputStream fis = new FileInputStream(keyFileName);
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
PublicKey pubKey = keyFactory.generatePublic(publicKeySpec);
return pubKey;
}
}
Decrypter.java:
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.*;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
public class Decrypter {
String keyFileName;
public Decrypter(String keyFileName) {
this.keyFileName = keyFileName;
}
public String rsaDecrypt(String str) throws Exception {
PrivateKey privateKey = readPrivateKeyFromFile(keyFileName);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] dec = Base64.decodeBase64(str);
byte[] utf8 = cipher.doFinal(Base64.decodeBase64(dec));
return Base64.encodeBase64String(utf8);
}
private PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception {
File filePrivateKey = new File(keyFileName);
FileInputStream fis = new FileInputStream(keyFileName);
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return privateKey;
}
}
In your Decrypter, you decode the Base64-encoded String into bytes, but then you decode that again. In your Encrypter, you take the bytes encrypted, and encode that into Base64 once. This is likely where your problem lies.
Strangely enough, you seem to perform more Base64 operations than necessary. For example, in Encrypter, you get the bytes of the string to encrypt. Why do you Base64-encode those bytes again?
Related
Regardless of the file size, 32 bytes of additional characters are appended to each decrypted file. I could just cut off the 32 bytes, but where did they come from and how can I avoid them in the output file?
This is my source code:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
public class EtAesCrypto {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private static final int KEY_LENGTH = 256;
private static final int SALT_LENGTH = 16;
private static final int IV_LENGTH = 12;
private static final int AUT_TAG_LENGTH = 128;
private static final int ITERATIONS = 100;
private static final String ALGORITHM = "AES";
private static final String SECRET_KEY_ALGORITHM = "PBKDF2WithHmacSHA256";
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
private String msg;
public void encrypt(String path2Original, String path2Encrypted, String password) {
try (FileOutputStream out = new FileOutputStream(path2Encrypted)) {
byte[] salt = new byte[SALT_LENGTH];
byte[] iv = new byte[IV_LENGTH];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(salt);
SecretKeyFactory factory = SecretKeyFactory.getInstance(SECRET_KEY_ALGORITHM);
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec skey = new SecretKeySpec(tmp.getEncoded(), ALGORITHM);
secureRandom.nextBytes(iv);
logger.trace("IV length: {}", iv.length);
out.write(salt);
out.write(iv);
Cipher ci = Cipher.getInstance(TRANSFORMATION);
GCMParameterSpec parameterSpec = new GCMParameterSpec(AUT_TAG_LENGTH, iv);
ci.init(Cipher.ENCRYPT_MODE, skey, parameterSpec);
try (FileInputStream in = new FileInputStream(path2Original)) {
processStream(ci, in, out);
}
} catch (Exception e) {
throw new RuntimeException("Encryption of file with id failed.");
}
}
public void decrypt(String path2Encrypted, OutputStream os, String password, String fileId) {
try (FileInputStream in = new FileInputStream(path2Encrypted)) {
doDecryption(in, os, password);
} catch (Exception e){
msg = String.format("Decryption of file with id '%s' failed.", fileId);
logger.warn("Decryption of file '{}' with id '{}' failed: {}", path2Encrypted, fileId, e.getMessage(), e);
throw new RuntimeException(msg);
}
}
public void decrypt(String path2Encrypted, String path2Decrypted, String password, String fileId) {
try (FileInputStream in = new FileInputStream(path2Encrypted)) {
try (FileOutputStream os = new FileOutputStream(path2Decrypted)) {
doDecryption(in, os, password);
}
} catch (Exception e){
msg = String.format("Decryption of file with id '%s' failed.", fileId);
logger.warn("Decryption of file '{}' with id '{}' failed: {}", path2Encrypted, fileId, e.getMessage(), e);
throw new RuntimeException(msg);
}
}
private void doDecryption(InputStream in, OutputStream out, String password) throws Exception {
byte[] salt = new byte[SALT_LENGTH];
byte[] iv = new byte[IV_LENGTH];
int saltBytes = in.read(salt);
int ivBytes = in.read(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance(SECRET_KEY_ALGORITHM);
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec skey = new SecretKeySpec(tmp.getEncoded(), ALGORITHM);
Cipher ci = Cipher.getInstance(TRANSFORMATION);
GCMParameterSpec parameterSpec = new GCMParameterSpec(AUT_TAG_LENGTH, iv);
ci.init(Cipher.ENCRYPT_MODE, skey, parameterSpec);
processStream(ci, in, out);
}
private void processStream(Cipher ci, InputStream in, OutputStream out) throws Exception {
byte[] inBuffer = new byte[1024];
int len;
while ((len = in.read(inBuffer)) != -1) {
byte[] outBuffer = ci.update(inBuffer, 0, len);
if (outBuffer != null)
out.write(outBuffer);
}
byte[] outBuffer = ci.doFinal();
if (outBuffer != null)
out.write(outBuffer);
}
}
You should use Cipher.DECRYPT_MODE when decrypting.
The additional bytes are the GCM tag (MAC). It is created during encryption and checked during decryption.
In GCM mode the process of encryption and decryption is identical (XOR), that's why decrypting with Cipher.ENCRYPT_MODE appears to work, except for the MAC part.
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
public class DJExampleDecryptCode
{
public static void main(String[] args)
{
try
{
String encryptedText = "q3sEN1NZZyseoFy9H3WIwNf9jpGrDTTqh/AticRV2pnb1KZ5lieuK5jw3JgctgYUnTE03xnMcOL50UGKZ4dbYEt5XGCZyNVgh1qVGF7Vgnvi5PKndnpKLcoSUJCcbu/lyLI2P+Zd7ZH0/tRKRn1zqrPAWUH3VjtUt7qkIcdIYyaoHP5I7eiZRk6FL9ugUQJnz8WFgM4mcRJ5Zs/NLdaXKeHMO4nPQBTOLNaPdNxW2MM+qlv0HN/fs4rPMRGUw0xXhjWsmSNqadASfn7UX4fL79CmGyKfm8ol4njZakZbsfes/zstc5Su0swycfFSkjXAjPjvMGdBs5/HSLXYAvQPoA==";
String TextToEncrypt = "Test";
String decryptedString = decrypt(encryptedText);
String encryptedString = encrypt(TextToEncrypt);
//Printing
System.out.println("Decrypted Text: " + decryptedString);
System.out.println("Encrypted Text: " + encryptedString);
}
catch (Exception e)
{
e.printStackTrace();
}
}
//public static String decrypt(String text, String privateKeyString) throws GeneralSecurityException
public static String decrypt(String text) throws GeneralSecurityException
{
String DJPrivateKey = ".....";
PrivateKey privateKey = stringToPrivateKey(DJPrivateKey);
byte[] dectyptedText = null;
try
{
final Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
dectyptedText = cipher.doFinal(base64Decode(text));
}
catch (Exception ex)
{
ex.printStackTrace();
}
return new String(dectyptedText);
}
public static String encrypt(String data) throws GeneralSecurityException
{
String PCMSPublicKey = "MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIV/0v/U5+6pgCAggAMBQGCCqGSIb3DQMHBAhSuqMZCoVAxgSCBMhKaVDCjOS9q0jEc+nUCEKQD73pHte/9nMdTkHbFGpu+1amzpY0YLhgqVTQhDp43amH6IvM3KfmM+9M5i0bXBksa+5la2kVl8Ntw6fzc1xFtcSMLb8CFkk0gV3l6kcKEo1rN2TiH3jGQz43DFHUJbnITWwY3SFCsWPZF2oegTAMSEKhOJ6h9bad3KoqNmqji6hdk9ONhQBarDrZGL9l+8GWnx9TyVxAVltBxzv0DRlqXlKhVkfV2XqkiECcilFHeoaI+cV6W1z8S9kFPdnm93QjCu88l1lG1a5ox4tu4dPHj4u7uVZKuEBkpr7HpF0uL+o+JEflNjUl/BYlS3++l6lfRpOp6mb2VVt1zQgoKVR1wZZeSoEqhJ/r75Krybq4TdXXqs4IdPZmSwIPTVM8n5ZvzUz/F+K46rYIQchz3GPCpKEPI/9+OhqUKtXe2KpPsZtD7hJ7+r1g99MwzEjyET6l7lLuIE2SpKS0wxZB5qb0+92+SfyPwQWIM5tfv1Gs7M8A2MFz9GclXsaGpt+mx0DQPiMkpdoB9e5GbO1PGlP3MWhUmQ6wwIUVVjGryJuvLFL+4psDeUzkdKilG9nPDVSWHLlCx1C3k8hcuJUy1bTihrFprcOEjuzGzmhp3IUQc+5Z4dydM/2AmYFCNmjySRKYZVRBPfPrcVfDo8P1lzlYeXLcWubMlwxyRfv/WjzJkyMlDSiYEEnkcYJrCgeocsU8qJ+yq1QAsTs361Svi2tQ7lJZjp1FtIdvMr+U32eW1Pri+vn4LWdPcPzxbrLHN/daV+l3Ttw493x0R7WMDnhcS8yhd8NlWoh43IzmQDCn33Lek7WS3HmSzTAg6bfxmYZf9Ogn86DR/q2c2ZKwbs3nloHdfkKklOOqgRPic7nP8khsd+pjTULZUDmKa3d0OW8Ps5fTY/GzWrJBLVEoM8bN0w3CUsHixSQOh1pMwJUiyAT/cJPZfru1gtUeNkSJ5u/atc6HaPc6sfrhLF6RWyhIYKyqoM2dyLFC3hi+N0ZLBZwp/tnIou24dtwlJnLvKCinzO0pUTJC2yOwsnfL57h+ikdd3xS9fMWwpiSdNps086japrp12GU9VyBZX8b9QEip/Hxw778OK1x853+WYM978wNPrFwIfWtQpvNZMi8Mt0WXDvfHiG8JK9PKDoS25iV8SrwZScfBTMIi95j419BuhcVca1fi0keEEKaqMzBus4Mgz421Qcy0xv2u81w90qoMyXBwadRODtrJBQIovHBCKVRkxEm64Rr3fCWGjralnKcjxDKa77qakFlFOyNJsplnlC0mc229E19JXlxpcdDlivscE727KLLYu8rPUEWMZY/PA0D9JH+u+52A81ur0vuCnTLF1V0WG8ECJwgVTbIfByPoi+MKuvmW1pvixwBXiIh7as95gVl47HAXmCYOj0bnD0yO/pFSLoiAURl0j2R/c/NtKjz5TQ9F3O3U83UojatwtIyc7xN6Bs+iwTPaBOJrI6Sbgc5yDJPFczhPQDSpFZVtTUSeq1UA7N7mogwQLAqawGBHQJ9JIapMl6uC7Y2nN9O4lYRtbQLBKpZ3xzIk9LrDyT3F/w+c3l/lVUz0X6lz746zNutl/6f6XKI5oeis7/b5rMHHYYE=";
PublicKey publicKey = stringToPublicKey(PCMSPublicKey);
byte[] enctyptedText = null;
try
{
final Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
enctyptedText = cipher.doFinal(base64Decode(data));
}
catch (Exception ex)
{
ex.printStackTrace();
}
return new String(enctyptedText);
}
public static byte[] base64Decode(String encodedString)
{
Base64 myBase64 = new Base64();
return myBase64.decode(encodedString);
}
public static PrivateKey stringToPrivateKey(String privateKeyString) throws GeneralSecurityException
{
byte[] clear = base64Decode(privateKeyString);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(clear);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey priv = fact.generatePrivate(keySpec);
Arrays.fill(clear, (byte) 0);
return priv;
}
public static PublicKey stringToPublicKey(String publicKeyString) throws GeneralSecurityException
{
byte[] clear = base64Decode(publicKeyString);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(clear);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pub = fact.generatePublic(keySpec);
Arrays.fill(clear, (byte) 0);
return pub;
}
}
I have the above java code that does encryption and decryption. The decryption works fine, which uses the private key, but when I ran the encryption part using the public key I hard-coded, I got the below errors,
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: DER input not a bit string
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
at DJExampleDecryptCode.stringToPublicKey(DJExampleDecryptCode.java:109)
at DJExampleDecryptCode.encrypt(DJExampleDecryptCode.java:64)
at DJExampleDecryptCode.main(DJExampleDecryptCode.java:26)
Caused by: java.security.InvalidKeyException: IOException: DER input not a bit string
at sun.security.x509.X509Key.decode(X509Key.java:397)
at sun.security.x509.X509Key.decode(X509Key.java:403)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:83)
can anyone give me some suggestions? thanks a lot
I am working on a concept of encryption and decryption using ecc.
I already generated public and private key. While I am encrypting the text I am getting this error:
java.security.InvalidKeyException: ECKeyAgreement requires ECPrivateKey
at
org.bouncycastle.jce.provider.JCEECDHKeyAgreement.engineInit(JCEECDHKeyAgreement.java:121)
at javax.crypto.KeyAgreement.init(KeyAgreement.java:462)
at javax.crypto.KeyAgreement.init(KeyAgreement.java:436)
at rbl2015.encryec.main(encryec.java:67)
This is my encryption Java file:
import java.io.File;
import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.ECParameterSpec;
import java.security.spec.EllipticCurve;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Scanner;
import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class encryec
{
KeyPairGenerator kpg;
EllipticCurve curve;
ECParameterSpec ecSpec;
KeyPair aKeyPair;
static KeyAgreement aKeyAgree;
KeyPair bKeyPair;
KeyAgreement bKeyAgree;
KeyFactory keyFac;
static String msg;
public static void main(String args[])
{
Security.addProvider(new BouncyCastleProvider());
Scanner ss=new Scanner(System.in);
try{
String path = "D:\\rp";
File filePublicKey = new File(path+"\\public.key");
FileInputStream fis = new FileInputStream(path+"\\public.key");
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
// Read Private Key.
File filePrivateKey = new File(path+"\\private.key");
fis = new FileInputStream(path+"\\private.key");
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
KeyFactory keyFactory = KeyFactory.getInstance("ECDH");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
aKeyAgree = KeyAgreement.getInstance("ECDH", "BC");
aKeyAgree.init(privateKey); // exception line
aKeyAgree.doPhase(publicKey, true);
byte[] aBys = aKeyAgree.generateSecret();
KeySpec aKeySpec = new DESKeySpec(aBys);
SecretKeyFactory aFactory = SecretKeyFactory.getInstance("DES");
Key aSecretKey = aFactory.generateSecret(aKeySpec);
Cipher aCipher = Cipher.getInstance(aSecretKey.getAlgorithm());
aCipher.init(Cipher.ENCRYPT_MODE, aSecretKey);
byte[] encText = aCipher.doFinal("Its Rahul".getBytes());
System.out.println(Base64.encodeBase64String(encText));
System.out.println(encText);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
I don't know what I am missing. I tried everything that I can to get the ECPrivateKey.
This is the code for generating the public and private key:
import java.io.*;
import java.security.*;
import java.security.spec.*;
public class Rahul {
public static void main(String args[]) {
Rahul rahul = new Rahul();
try {
String path = "D:\\rp";
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(1024);
KeyPair generatedKeyPair = keyGen.genKeyPair();
System.out.println("Generated Key Pair");
rahul.dumpKeyPair(generatedKeyPair);
rahul.SaveKeyPair(path, generatedKeyPair);
KeyPair loadedKeyPair = rahul.LoadKeyPair(path, "DSA");
System.out.println("Loaded Key Pair");
rahul.dumpKeyPair(loadedKeyPair);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
private void dumpKeyPair(KeyPair keyPair) {
PublicKey pub = keyPair.getPublic();
System.out.println("Public Key: " + getHexString(pub.getEncoded()));
PrivateKey priv = keyPair.getPrivate();
System.out.println("Private Key: " + getHexString(priv.getEncoded()));
}
private String getHexString(byte[] b) {
String result = "";
for (int i = 0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
public void SaveKeyPair(String path, KeyPair keyPair) throws IOException {
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
// Store Public Key.
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream(path + "/public.key");
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();
// Store Private Key.
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
privateKey.getEncoded());
fos = new FileOutputStream(path + "/private.key");
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
}
public KeyPair LoadKeyPair(String path, String algorithm)
throws IOException, NoSuchAlgorithmException,
InvalidKeySpecException {
// Read Public Key.
File filePublicKey = new File(path + "/public.key");
FileInputStream fis = new FileInputStream(path + "/public.key");
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
// Read Private Key.
File filePrivateKey = new File(path + "/private.key");
fis = new FileInputStream(path + "/private.key");
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
// Generate KeyPair.
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return new KeyPair(publicKey, privateKey);
}
}
You should try and create an EC(DH) key pair instead of a DSA key pair. Although the general method of operation is identical (both ECDSA and DSA are based on the Diffie-Hellman problem) the key types are certainly not.
I am becoming intermediate java programmer. I have tried hard to find out how to sign and read digital signatures in java for a net program i have been working on. I have been able to generate private and public keys with the tutorial at http://docs.oracle.com/javase/tutorial/security/apisign/index.html but have not been able to do anything with them. Although I know how to generate keys i didn't put it in because i wasn't sure if i had done them correctly.
Here is a simplified version of my code:
Main class:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
Main main = new Main();
Scanner s = new Scanner(System.in);
while (true) {
//This is where i added a command detector so that the program can be in one class
System.out.println("Choose a command from the following:\nGenerate keys\nSign message\nRead message");
String command = s.nextLine();
if (command.equalsIgnoreCase("Generate key")
|| command.equalsIgnoreCase("Generate")) {
/* The code for generating the keys is here */
File f = new File("C:\\Users\\spencer\\Documents\\Stack ex\\src\\app","public.key");
File fi = new File("C:\\Users\\spencer\\Documents\\Stack ex\\src\\app","private.key");
if(!f.isFile()||!fi.isFile()) {
Make make =new Make();
Make.main(args);
}
else{
try {
String path = "C:\\Users\\spencer\\Documents\\ds test 3\\src\\app";
KeyPair loadedKeyPair = main.LoadKeyPair(path, "DSA");
System.out.println("Key pair already exists!");
System.out.println("Loaded Key Pair:");
main.dumpKeyPair(loadedKeyPair);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
if (command.equalsIgnoreCase("Sign message")
|| command.equalsIgnoreCase("Sign")) {
long signature = 0;
System.out.println("What is your private key");
String pkey = s.nextLine();
long prkey = Long.parseLong(pkey);
System.out.println("What is you message");
String message = s.nextLine();
/* The code for signing the message goes here */
System.out.println("Signature:"+signature);
} else if (command.equalsIgnoreCase("Read message")
|| command.equalsIgnoreCase("Read")) {
String message = null;
System.out.println("What is the signature");
String sign = s.nextLine();
long signature = Long.parseLong(sign);
/* The code for reading the message goes here */
System.out.println(message);
}
}
}
private void dumpKeyPair(KeyPair keyPair) {
PublicKey pub = keyPair.getPublic();
System.out.println("Public Key: " + getHexString(pub.getEncoded()));
PrivateKey priv = keyPair.getPrivate();
System.out.println("Private Key: " + getHexString(priv.getEncoded()));
}
private String getHexString(byte[] b) {
String result = "";
for (int i = 0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
public KeyPair LoadKeyPair(String path, String algorithm)
throws IOException, NoSuchAlgorithmException,
InvalidKeySpecException {
// Read Public Key.
File filePublicKey = new File(path + "/public.key");
FileInputStream fis = new FileInputStream(path + "/public.key");
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
// Read Private Key.
File filePrivateKey = new File(path + "/private.key");
fis = new FileInputStream(path + "/private.key");
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
// Generate KeyPair.
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return new KeyPair(publicKey, privateKey);
}
}
Make class:
import java.io.*;
import java.security.*;
import java.security.spec.*;
public class Make {
public static void main(String args[]) {
Make adam = new Make();
try {
String path = "C:\\Users\\spencer\\Documents\\Stack ex\\src\\app";
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(512);
KeyPair generatedKeyPair = keyGen.genKeyPair();
System.out.println("Generated Key Pair");
adam.dumpKeyPair(generatedKeyPair);
adam.SaveKeyPair(path, generatedKeyPair);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
private void dumpKeyPair(KeyPair keyPair) {
PublicKey pub = keyPair.getPublic();
System.out.println("Public Key: " + getHexString(pub.getEncoded()));
PrivateKey priv = keyPair.getPrivate();
System.out.println("Private Key: " + getHexString(priv.getEncoded()));
}
private String getHexString(byte[] b) {
String result = "";
for (int i = 0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
public void SaveKeyPair(String path, KeyPair keyPair) throws IOException {
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
// Store Public Key.
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream(path + "/public.key");
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();
// Store Private Key.
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
privateKey.getEncoded());
fos = new FileOutputStream(path + "/private.key");
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
}
}
I need a little help with signing and reading the signature.
I convert the secretkey into bytes with following code
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
byte[] bkey=key.getEncoded();
Now how do I get the key from bkey? I tried:
SecretKeySpec secretkey = new SecretKeySpec(bkey,"DES");
SecretKeyFactory sfkey = SecretKeyFactory.getInstance("DES");
SecretKey skey = sfkey.generateSecret(secretkey);
I get the following error:
Error during Exception java.security.spec.InvalidKeySpecException: Inappropriate key specification
This should work
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
byte[] data = key.getEncoded();
SecretKey key2 = new SecretKeySpec(data, 0, data.length, "DES");
Try some of this code...
import javax.crypto.Cipher;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.InvalidKeyException;
public class DESede {
private static String algorithm = "DESede";
private static Key key = null;
private static SecretKey secretKey = null;
private static Cipher cipher = null;
private static DESede obj = new DESede();
private DESede() {
try {
key = KeyGenerator.getInstance(algorithm).generateKey();
KeyGenerator.getInstance(algorithm).getProvider();
byte[] keyBytes = key.getEncoded();
String keyFormat = key.getFormat();
String keyAlgorithm = key.getAlgorithm();
String keyString = new String(keyBytes);
System.out.println("Key Format::" + keyFormat);
System.out.println("Key Algorithm::" + keyAlgorithm);
System.out.println("Key String::" + keyString);
keyString.getBytes();
secretKey = new SecretKeySpec(keyBytes, 0, keyBytes.length, "DESede");
byte[] secretKeyBytes = key.getEncoded();
String secretKeyFormat = key.getFormat();
String secretKeyAlgorithm = key.getAlgorithm();
String secretKeyString = new String(secretKeyBytes);
System.out.println("Secret Key Format::" + secretKeyFormat);
System.out.println("Secret Key Algorithm::" + secretKeyAlgorithm);
System.out.println("Secret Key String::" + secretKeyString);
String keyNewString = "bXŒ*êÂÕê›æOÄ’Îý‘ãô|8¶Ë1";
byte[] keyNewBytes = keyString.getBytes();
secretKey = new SecretKeySpec(keyBytes, 0, keyBytes.length, "DESede");
cipher = Cipher.getInstance(algorithm);
} catch (Exception e) {
}
}
public static DESede getInstance() {
return obj;
}
public static byte[] encrypt(String input) throws InvalidKeyException,
BadPaddingException, IllegalBlockSizeException {
System.out.println("Inside encrypt()");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] inputBytes = input.getBytes();
System.out.println("Exit encrypt()");
return cipher.doFinal(inputBytes);
}
public static String decrypt(byte[] encryptionBytes)
throws InvalidKeyException, BadPaddingException,
IllegalBlockSizeException {
System.out.println("Inside decrypt()");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] recoveredBytes = cipher.doFinal(encryptionBytes);
String recovered = new String(recoveredBytes);
System.out.println("Exiting decrypt()");
return recovered;
}
public static void main(String args[]) throws InvalidKeyException,
BadPaddingException, IllegalBlockSizeException {
byte[] encryptedValue = DESede.encrypt("plz try encrypt and decrypt me");
System.out.println("encryptedValue::" + encryptedValue);
String decryptedValue = DESede.decrypt(encryptedValue);
System.out.println("decryptedValue::" + decryptedValue);
}
}