I am trying to encrypt and decrypt a symmetric key file (256 and 128) using RSAES - OAEP but I am getting error while encrypting :
File Sizes to encrypt: 256 and 128
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import java.util.Arrays;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
public static void main(String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.generateKeyPair();
String inputPath = "/home/roxane/Music/test_09";
String inFile = "/home/roxane/Downloads/s_key";
String encfile = "/home/roxane/Music/s_key.enc";
// get key pair
PublicKey pub = kp.getPublic();
PrivateKey PrivateKey = kp.getPrivate();
// Write Key Pair
try (FileOutputStream out = new FileOutputStream(inputPath + ".key")) {
out.write(kp.getPrivate().getEncoded());
}
try (FileOutputStream out = new FileOutputStream(inputPath + ".pub")) {
out.write(kp.getPublic().getEncoded());
}
//restore kEys
byte[] pubbytes = Files.readAllBytes(Paths.get(inputPath + ".pub"));
X509EncodedKeySpec ks = new X509EncodedKeySpec(pubbytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pub1 = kf.generatePublic(ks);
byte[] privbytes = Files.readAllBytes(Paths.get(inputPath + ".key"));
PKCS8EncodedKeySpec ks1 = new PKCS8EncodedKeySpec(privbytes);
KeyFactory kf1 = KeyFactory.getInstance("RSA");
PrivateKey pvt = kf1.generatePrivate(ks1);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-512ANDMGF1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, pvt);
try (FileInputStream in = new FileInputStream(inFile);
FileOutputStream out = new FileOutputStream(encfile)) {
processFile(cipher, in, out);
}
}
static private void processFile(Cipher ci,InputStream in,OutputStream out)
throws javax.crypto.IllegalBlockSizeException,
javax.crypto.BadPaddingException,
java.io.IOException
{
byte[] ibuf = new byte[1024];
int len;
while ((len = in.read(ibuf)) != -1) {
byte[] obuf = ci.update(ibuf, 0, len);
if ( obuf != null ) out.write(obuf);
}
byte[] obuf = ci.doFinal();
if ( obuf != null ) out.write(obuf);
}
Error: Exception in thread "main" java.security.InvalidKeyException: OAEP cannot be used to sign or verify signatures
Requesting help in the code encrytption and decryption of the files compatible with openssl. I am open to use bouncycastle if required
Related
I am trying to do a simple encrypt/decrypt with asymmetric keys in JAVA using RSA keys and i have some troubles. This is my code :
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.RandomAccessFile;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
public class AsymmetricCipherTestFiles
{
public static void main(String[] unused) throws Exception
{
// 1. Generating keys
System.out.println("Generating keys ...");
PublicKey publicKey;
PrivateKey privateKey;
// generateKeys(512);
// 2. read them from file
System.out.println("Read from file");
publicKey = readPublicKeyFromFile("public.key");
privateKey = readPrivateKeyFromFileTest("private.key");
System.exit(0);
// 3. encrypt data
System.out.println("Encrypt data");
byte[] dataBytes = "some string to encrypt".getBytes();
byte[] encBytes = encrypt(dataBytes, publicKey, "RSA");
printByteArray(encBytes);
// 4. decrypt data
byte[] decBytes = decrypt(encBytes, privateKey, "RSA");
printByteArray(decBytes);
// String decryptedThing = convert(decBytes);
}
public static void generateKeys(int keySize) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException
{
// Create key
// System.out.println("Generating keys");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(keySize);
KeyPair kp = kpg.genKeyPair();
/*
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();
*/
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(),RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(),RSAPrivateKeySpec.class);
saveKeyToFile("bin/public.key", pub.getModulus(), pub.getPublicExponent());
saveKeyToFile("bin/private.key", priv.getModulus(),priv.getPrivateExponent());
// System.out.println("Keys generated");
}
private static byte[] encrypt(byte[] inpBytes, PublicKey key,String xform) throws Exception
{
Cipher cipher = Cipher.getInstance(xform);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(inpBytes);
}
private static byte[] decrypt(byte[] inpBytes, PrivateKey key,String xform) throws Exception
{
Cipher cipher = Cipher.getInstance(xform);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(inpBytes);
}
public static String convert(byte[] data)
{
StringBuilder sb = new StringBuilder(data.length);
for (int i = 0; i < data.length; ++ i)
{
if (data[i] < 0) throw new IllegalArgumentException();
sb.append((char) data[i]);
}
return sb.toString();
}
public static PublicKey readPublicKeyFromFile(String keyFileName) throws IOException
{
InputStream in = (InputStream) AsymmetricCipherTestFiles.class.getResourceAsStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream( in ));
try
{
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);
return pubKey;
}
catch (Exception e)
{
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
public static PrivateKey readPrivateKeyFromFile(String keyFileName) throws IOException
{
InputStream in = (InputStream) AsymmetricCipherTestFiles.class.getResourceAsStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream( in ));
try
{
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
byte[] byteArray = new byte[512];
byteArray = m.toByteArray();
KeySpec keySpec = new PKCS8EncodedKeySpec(byteArray);
// RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey privateKey = fact.generatePrivate(keySpec);
return privateKey;
}
catch (Exception e)
{
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
public static PrivateKey readPrivateKeyFromFileTest(String filename) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException
{
RandomAccessFile raf = new RandomAccessFile(filename, "r");
byte[] buf = new byte[(int)raf.length()];
raf.readFully(buf);
raf.close();
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(buf);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(kspec);
return privKey;
}
public static void saveKeyToFile(String fileName,BigInteger mod, BigInteger exp) throws IOException
{
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
try
{
oout.writeObject(mod);
oout.writeObject(exp);
}
catch (Exception e)
{
throw new IOException("Unexpected error", e);
}
finally
{
oout.close();
}
}
public static void printByteArray(byte[] byteArray)
{
int increment = 0;
for(byte b : byteArray)
{
System.out.println("B["+increment+"] = "+b);
increment++;
}
}
}
When i run it it gives me this error :
Generating keys ...
Read from file
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=109, too big.
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source)
at java.security.KeyFactory.generatePrivate(Unknown Source)
at AsymmetricCipherTestFiles.readPrivateKeyFromFileTest(AsymmetricCipherTestFiles.java:160)
at AsymmetricCipherTestFiles.main(AsymmetricCipherTestFiles.java:40)
Caused by: java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=109, too big.
at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(Unknown Source)
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(Unknown Source)
at sun.security.rsa.RSAKeyFactory.generatePrivate(Unknown Source)
... 4 more
The thing is that at generating/reading/encrypting with public key everything works smoothly, the error occurs when reading private key and trying to get it into an PrivateKey object.
What i am doing wrong and how i may solve this?
Thanks.
You're saving the key with two writeObject() calls but retreiving it with a single readFully() call. You need to either:
save the key with write(byte[]), supplying the result of getEncoded(), and read it with readFully(), or
save it with writeObject() and read it with readObject().
Not a mixture of the two.
I am trying to encrypt and decrypt a String using jks Keystore file.But while decryption i am getting following error...
Here is my class for encryption and decryption :
package com.Encrypt;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableEntryException;
import java.security.UnrecoverableKeyException;
import java.security.KeyStore.PrivateKeyEntry;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.binary.Base64;
public class Encrypt {
public String encyptCard(String card) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnrecoverableKeyException{
FileInputStream is = new FileInputStream("C:/Users/admin/Desktop/keystore/ksjksformat.jks");
String keystpassw = "9801461740";
String alias = "ksjksformat";
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(is,keystpassw.toCharArray() );
Certificate cert = ks.getCertificate(alias);
PublicKey publicKey = cert.getPublicKey();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherData = cipher.doFinal(card.getBytes());
String cipherData1 = Base64.encodeBase64String(cipherData);
return cipherData1;
}
public String decrypte (String encCardNo) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableEntryException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
FileInputStream is = new FileInputStream("C:/Users/admin/Desktop/keystore/ksjksformat.jks");
String keystpassw = "9801461740";
String alias = "ksjksformat";
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(is,keystpassw.toCharArray() );
Key key = ks.getKey(alias, keystpassw.toCharArray());
Certificate cert = ks.getCertificate(alias);
PublicKey publicKey = cert.getPublicKey();
new KeyPair(publicKey, (PrivateKey) (key));
KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(keystpassw.toCharArray());
KeyStore.PrivateKeyEntry pkentry = (PrivateKeyEntry) ks.getEntry(alias, protParam);
PrivateKey myPrivateKey =pkentry.getPrivateKey();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, myPrivateKey);
byte[] cipherData = cipher.doFinal(encCardNo.getBytes());
String decrypted =Base64.decodeBase64(cipherData).toString();
return decrypted;
}
}
Here is my class where i am calling these methods : -
package com.Encrypt;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableEntryException;
import java.security.cert.CertificateException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
public class CryptoHelper {
public static void main(String[] argv) throws InvalidKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, IOException, UnrecoverableEntryException {
Encrypt obj = new Encrypt();
String answerEnc = obj.encyptCard("student");
System.out.println("encrypted data----------->"+answerEnc);
String Orginial_data = obj.decrypte(answerEnc);
System.out.println("Decrypted data-------->"+Orginial_data);
}
}
now i am getting this error : -
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.Encrypt.Encrypt.decrypte(Encrypt.java:56)
at com.Encrypt.CryptoHelper.main(CryptoHelper.java:17)
This error is while decryption at line
byte[] cipherData = cipher.doFinal(encCardNo.getBytes());
in public String decrypte (String encCardNo) method. Please explain how can I resolve this one.
#Maarten Bodewes answer is correct we have to decode before decryption ..
Thanks #Maarten BodewesHere is the code for decryption method which is returning correct output. `
public String decrypte (String encCardNo) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableEntryException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
FileInputStream is = new FileInputStream("C:/Users/admin/Desktop/keystore/ksjksformat.jks");
String keystpassw = "9801461740";
String alias = "ksjksformat";
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(is,keystpassw.toCharArray() );
Key key = ks.getKey(alias, keystpassw.toCharArray());
Certificate cert = ks.getCertificate(alias);
PublicKey publicKey = cert.getPublicKey();
new KeyPair(publicKey, (PrivateKey) (key));
KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(keystpassw.toCharArray());
KeyStore.PrivateKeyEntry pkentry = (PrivateKeyEntry) ks.getEntry(alias, protParam);
PrivateKey myPrivateKey =pkentry.getPrivateKey();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, myPrivateKey);
byte[] decoded = Base64.decodeBase64(encCardNo);
byte[] cipherData = cipher.doFinal(decoded);
return new String(cipherData);
}`
You need to decode before decrypting, not after.
As a special service for accepting my answer while posting your own, a bit of a rewrite of decrypte:
public String decrypte(final String encCardNo) throws IllegalBlockSizeException,
BadPaddingException {
// --- setup (should be stored differently)
final char[] keystpassw = "9801461740".toCharArray();
final String alias = "ksjksformat";
// --- retrieve private key from store
final PrivateKey key;
try (final FileInputStream is = new FileInputStream(
"C:/Users/admin/Desktop/keystore/ksjksformat.jks")) {
final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(is, keystpassw);
key = (PrivateKey) ks.getKey(alias, keystpassw);
} catch (final KeyStoreException | IOException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException e) {
throw new IllegalStateException("Could not load key from key store", e);
}
// --- initialize cipher
final Cipher cipher;
try {
// should use OAEP instead
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
} catch (final NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalStateException(
"RSA PKCS v1.5 should always be available", e);
} catch (final InvalidKeyException e) {
throw new IllegalStateException("Key is not an RSA private key", e);
}
// --- decode
final byte[] decoded;
try {
decoded = Base64.getDecoder().decode(encCardNo);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid encoded ciphertext", e);
}
// --- decrypt
final byte[] cipherData = cipher.doFinal(decoded);
final String cardNo = new String(cipherData, StandardCharsets.US_ASCII);
// --- clean up
try {
key.destroy();
} catch (final DestroyFailedException e) {
// we tried, possibly log this
}
Arrays.fill(cipherData, (byte) 0);
return cardNo;
}
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 have an RSA private key that I am trying to decrypt another files contents that has an AES key in it. So far all I can seem to get to return from the processes is jargon. Not really sure what I am doing wrong in the below code. I have looked on google and have seen this done at least a 100 different ways.
import java.io.*;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.GeneralSecurityException;
import java.security.spec.PKCS8EncodedKeySpec;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
public class RsaEncryption {
private Cipher _pkCipher;
public RsaEncryption() throws GeneralSecurityException {
// create RSA public key cipher
_pkCipher = Cipher.getInstance("RSA");
}
public String loadKey(File in, String privateKey) throws GeneralSecurityException, IOException, Exception {
privateKey = privateKey.replaceAll("-+.*?-+", "");
byte[] encodedKey = Base64.decodeBase64(privateKey);
// create private key
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKey pk = (RSAPrivateKey) kf.generatePrivate(privateKeySpec);
// read AES key
_pkCipher.init(Cipher.DECRYPT_MODE, pk);
byte[] encryptedBytes = FileUtils.readFileToByteArray(in);
ByteArrayInputStream fileIn = new ByteArrayInputStream(encryptedBytes);
CipherInputStream cis = new CipherInputStream(fileIn, _pkCipher);
DataInputStream dis = new DataInputStream(cis);
byte[] decryptedData = new byte[32];
dis.read(decryptedData);
String key = new String(decryptedData);
return key;
}
}
UPDATE
New way with bouncy castles pem converter still not working
import java.io.StringReader;
import java.io.File;
import java.io.IOException;
import java.security.KeyPair;
import java.security.interfaces.RSAPrivateKey;
import java.security.GeneralSecurityException;
import java.security.interfaces.RSAPublicKey;
import javax.crypto.Cipher;
import org.apache.commons.io.FileUtils;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
public class RsaEncryption {
private Cipher _pkCipher;
private RSAPrivateKey _PrivateKey;
private RSAPublicKey _PublicKey;
public RsaEncryption(String privateKey) throws GeneralSecurityException, IOException {
loadKey(privateKey);
// create RSA public key cipher
_pkCipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
}
private void loadKey(String privateKey) throws IOException {
PEMParser pemParser = new PEMParser(new StringReader(privateKey));
PEMKeyPair pemKeyPair = (PEMKeyPair) pemParser.readObject();
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
KeyPair keyPair = converter.getKeyPair(pemKeyPair);
_PrivateKey = (RSAPrivateKey) keyPair.getPrivate();
_PublicKey = (RSAPublicKey) keyPair.getPublic();
pemParser.close();
}
public String decrypt(File in) throws GeneralSecurityException , IOException{
_pkCipher.init(Cipher.DECRYPT_MODE, _PrivateKey);
byte[] encryptedBytes = FileUtils.readFileToByteArray(in);
String key = new String(_pkCipher.doFinal(encryptedBytes));
System.out.println(key);
return key;
}
public RSAPrivateKey getPrivateKey() { return _PrivateKey; }
public RSAPublicKey getPublicKey() { return _PublicKey; }
}
RSA can only encrypt a small amount of data which must be processed as a chunk. You don't need a stream for that. Simply call
byte[] aesKey = _pkCipher.doFinal(FileUtils.readFileToByteArray(in));
to get the AES key.
JCE jars where in the wrong directory worked just fine once they got put in the correct directory.
The following code is a try to encrypt data using AES with asymmetric key:
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
public class AsyncronousKeyTest {
private final Cipher cipher;
private final KeyFactory keyFactory;
private final RSAPrivateKey privKey;
private AsyncronousKeyTest() throws Exception {
cipher = Cipher.getInstance("AES/CBC/NoPaddin", "BC");
keyFactory = KeyFactory.getInstance("AES", "BC");
// create the keys
RSAPrivateKeySpec privKeySpec = new RSAPrivateKeySpec(new BigInteger(
"d46f473a2d746537de2056ae3092c451", 16), new BigInteger("57791d5430d593164082036ad8b29fb1",
16));
privKey = (RSAPrivateKey) keyFactory.generatePrivate(privKeySpec);
}
public void generateAuthorizationAct(OutputStream outputStream) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("AES", "BC");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger("d46f473a2d746537de2056ae3092c451",
16), new BigInteger("11", 16));
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
byte[] data = new byte[] {0x01};
byte[] encrypted = encryptAO(pubKey, data);
outputStream.write(encrypted);
}
/** Encrypt the AuthorizationObject. */
public byte[] encryptAO(Key pubKey, byte[] data) throws Exception {
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherText = cipher.doFinal(data);
return cipherText;
}
public byte[] decrypt(byte[] cipherText) throws Exception {
cipher.init(Cipher.DECRYPT_MODE, privKey);
byte[] decyptedData = cipher.doFinal(cipherText);
return decyptedData;
}
public static void main(String[] args) throws Exception {
System.out.println("start");
AsyncronousKeyTest auth = new AsyncronousKeyTest();
auth.generateAuthorizationAct(System.out);
System.out.println("done");
}
}
but at line
cipher = Cipher.getInstance("AES/CBC/NoPaddin", "BC");
it throws
NoSuchPaddingException: Padding NoPaddin unknown.
What is this? And how to solve?
"Padding" is not "Paddin". The "g" matters.
Also, "encrypting data with AES with asymmetric key" makes no sense. A RSA key, as its name says, is for RSA, not for AES. AES uses a symmetric key, namely an array of (arbitrary) bytes of length 16, 24 or 32 bytes. A RSA key is a mathematical objects consisting of two integers, one of which being quite big (typically 1024 bits).