Im trying to write a program for encrypting, signing and decrypting files using private public keys . While running the program below i receive the following error -
Exception in thread "main" java.security.InvalidKeyException: Wrong format: RAW bytes needed at com.sun.crypto.provider.CipherCore.getKeyBytes(CipherCore.java:623) at com.sun.crypto.provider.CipherCore.init(CipherCore.java:494) at com.sun.crypto.provider.CipherCore.init(CipherCore.java:458) at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:307) at javax.crypto.Cipher.init(Cipher.java:1226) at
javax.crypto.Cipher.init(Cipher.java:1166) at
Main.main(Main.java:87)
MY CODE
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.security.*;
import java.security.cert.CertificateException;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class Main
{
public static void main(String[] args) throws IOException, UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, NoSuchPaddingException, CertificateException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, SignatureException{
//open the file containing keys
File file = new File("keys/ks_file.jks");
//cipher object that will hold the information
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
//create keystore object from stored keys inside the file
KeyStore keystore = loadKeyStore(file, "sergey", "JKS");
//messageDigest instance
MessageDigest md = MessageDigest.getInstance("SHA1");
//singanture instance
Signature dsa = Signature.getInstance("SHA1withDSA");
//params for getting keys
String allias = "enc_key", password = "sergey";
SecureRandom s_random = SecureRandom.getInstance("SHA1PRNG");
//create random bytes for semtric key
byte key_bytes[] = new byte[16];
s_random.setSeed(711);
s_random.nextBytes(key_bytes);
Key key = new SecretKeySpec(key_bytes, "AES");
Key key_enc = keystore.getKey(allias, password.toCharArray());
KeyPair enc_key = null;
if (key_enc instanceof PrivateKey) {
// Get certificate of public key
java.security.cert.Certificate cert = keystore.getCertificate(allias);
// Get public key
PublicKey publicKey = cert.getPublicKey();
enc_key = new KeyPair(publicKey, (PrivateKey) key_enc);
}
//cipher the file
aes.init(Cipher.ENCRYPT_MODE, key);
FileInputStream fis;
FileOutputStream fos;
CipherInputStream cis;
fis = new FileInputStream("tmp/a.txt");
cis = new CipherInputStream(fis, aes);
fos = new FileOutputStream("tmp/b.txt");
byte[] b = new byte[8];
int i = cis.read(b);
byte[] bytes = ByteBuffer.allocate(4).putInt(i).array();
//update message digest for signature
md.update(bytes);
while (i != -1) {
fos.write(b, 0, i);
i = cis.read(b);
bytes = ByteBuffer.allocate(4).putInt(i).array();
md.update(bytes);
}
fis.close();
cis.close();
fos.close();
//encode the secret key
/**************** ERROR HAPPENS IN NEXT LINE - LINE 87 *******************/
aes.init(Cipher.ENCRYPT_MODE, (Key)enc_key.getPublic());
byte[] cipherKey = aes.doFinal(key.toString().getBytes());
//we save the final digest
byte[] hash = md.digest();
//init singature with private key
dsa.initSign(enc_key.getPrivate());
//update the signature with the hash aster digest
dsa.update(hash);
//final signature
byte[] sig = dsa.sign();
//creating config xml
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("config");
doc.appendChild(rootElement);
// signature elements
Element sig_xml = doc.createElement("sig");
rootElement.appendChild(sig_xml);
sig_xml.setAttribute("value", sig.toString());
// key element
Element key_xml = doc.createElement("key");
rootElement.appendChild(key_xml);
key_xml.setAttribute("value", cipherKey.toString());
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("./config.xml"));
transformer.transform(source, result);
System.out.println("File saved!");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
/**
* Reads a Java keystore from a file.
*
* #param keystoreFile
* keystore file to read
* #param password
* password for the keystore file
* #param keyStoreType
* type of keystore, e.g., JKS or PKCS12
* #return the keystore object
* #throws KeyStoreException
* if the type of KeyStore could not be created
* #throws IOException
* if the keystore could not be loaded
* #throws NoSuchAlgorithmException
* if the algorithm used to check the integrity of the keystore
* cannot be found
* #throws CertificateException
* if any of the certificates in the keystore could not be loaded
*/
public static KeyStore loadKeyStore(final File keystoreFile,
final String password, final String keyStoreType)
throws KeyStoreException, IOException, NoSuchAlgorithmException,
CertificateException {
if (null == keystoreFile) {
throw new IllegalArgumentException("Keystore url may not be null");
}
final URI keystoreUri = keystoreFile.toURI();
final URL keystoreUrl = keystoreUri.toURL();
final KeyStore keystore = KeyStore.getInstance(keyStoreType);
InputStream is = null;
try {
is = keystoreUrl.openStream();
keystore.load(is, null == password ? null : password.toCharArray());
} finally {
if (null != is) {
is.close();
}
}
return keystore;
}
}
The specific line, in which the exception occurs is:
aes.init(Cipher.ENCRYPT_MODE, (Key)enc_key.getPublic());
AES is a symmetric cipher algorithm, for this it needs a symmetric key, not a public key.
In order to create symmetric key, use helper class SecretKeySpec.
Your encryption scheme should create a random sequence of bits as a key material for AES cipher, and then encrypt/decrypt this key material with Public/Private keys.
The message itself should be encrypted/decrypted with AES key.
Related
So I have generated a key pair in keytool and generated a symmetric key and the encrypted a String with the symmetric key and then encrypted the symmetric key. Now I have to decrypt the symmetric key and I am having some trouble. The code I am using for decryption is not throwing back any errors but it is not actually doing anything either and I am not sure what I am doing wrong.
package ReadFileExample;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyException;
import java.security.KeyPair;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.security.cert.Certificate;
import java.security.KeyStore;
import java.security.Key;
import java.io.FileInputStream;
public class generatekey {
static Cipher cipher;
public static void main(String[] args) throws Exception {
// generating a symmetric key using the AES algorithm
KeyGenerator generator = KeyGenerator.getInstance("AES");
// 128 bit key
generator.init(128);
//generates a secret key
SecretKey secretkey = generator.generateKey();
// returns an AES cipher
cipher = Cipher.getInstance("AES");
//print key
System.out.println("Key: " + cipher);
String plainText = "Hello World";
// call to method encrypt
String encryptedText = encrypt(plainText, secretkey);
// print orignial text and encrypted text
System.out.println("Plain Text: " + plainText);
System.out.println("Encrypted Text: " + encryptedText);
String publicKey = "C:/Users/girgich/public.cert";
// allows to write data to a file
FileOutputStream fos = null;
// write bytes to file
BufferedOutputStream bos = null;
// create file to which data needs to be written
String fileName = "C:/Users/girgich/newFile.txt";
try{
// allows written data to go into the written path
fos = new FileOutputStream(fileName);
// converts written data into bytes
bos = new BufferedOutputStream(fos);
// writes the encrypted text into file
bos.write(encryptedText.getBytes());
System.out.println("encryptedText has been written successfully in "
+fileName);
// allows to catch bug in code
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
// check for null exception
if (bos != null){
bos.close();
}
// check for null exception
if (fos != null){
fos.close();
}
} catch (IOException e){
e.printStackTrace();
}
}
// creates a file input stream by opening a path to the file needed
FileInputStream fin = new
FileInputStream("C:/Users/girgich/public.cert");
// implements the X509 certificate type
CertificateFactory f = CertificateFactory.getInstance("X.509");
// initalizes data found in the file
X509Certificate certificate =
(X509Certificate)f.generateCertificate(fin);
// gets public key from this certificate
PublicKey pk = certificate.getPublicKey();
System.out.println(pk);
String encryptedTextKey = encryptedKey(pk, secretkey);
System.out.println("Encrypted Key: " + encryptedTextKey);
// allows to write data to a file
FileOutputStream newFos = null;
// write bytes to file
BufferedOutputStream newBos = null;
// create file to which data needs to be written
String fileNameKey = "C:/Users/girgich/symmetric.txt";
try{
// allows written data to go into the written path
newFos = new FileOutputStream(fileNameKey);
// converts written data into bytes
newBos = new BufferedOutputStream(newFos);
// writes the encrypted text into file
newBos.write(encryptedTextKey.getBytes());
System.out.println("encryptedKey has been written successfully in "
+fileNameKey);
// allows to catch bug in code
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
// check for null exception
if (newBos != null){
newBos.close();
}
// check for null exception
if (newFos != null){
newFos.close();
}
} catch (IOException e){
e.printStackTrace();
}
}
String decrypt = (encryptedTextKey);
}
public static String encrypt(String plainText, SecretKey secretkey) throws
Exception {
//Encodes the string into a sequence of bytes
byte[] plainTextByte = plainText.getBytes();
//intialize cipher to encryption mode
cipher.init(Cipher.ENCRYPT_MODE, secretkey);
//data is encrypted
byte[] encryptedByte = cipher.doFinal(plainTextByte);
Base64.Encoder encoder = Base64.getEncoder();
//encodes bytes into a string using Base64
String encryptedText = encoder.encodeToString(encryptedByte);
// return the string encrypted text to the main method
return encryptedText;
}
public static String encryptedKey(PublicKey pk, SecretKey secretkey) throws Exception {
// data written to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// writes data types to the output stream
ObjectOutputStream writter = new ObjectOutputStream(baos);
//specific object of secretkey is written to the output stream
writter.writeObject(secretkey);
//creates a byte array
byte[] plainTextByteKey = baos.toByteArray();
//creates a cipher using the RSA algorithm
Cipher cipher = Cipher.getInstance("RSA");
// initalizes cipher for encryption using the public key
cipher.init(Cipher.ENCRYPT_MODE, pk);
//encrypts data
byte[] encryptedByteKey = cipher.doFinal(plainTextByteKey);
Base64.Encoder encoderKey = Base64.getEncoder();
// encodes the byte array into a string.
String encryptedTextKey = encoderKey.encodeToString(encryptedByteKey);
return encryptedTextKey;
}
public void decrypt(String encryptedTextKey) {
byte[] decryptedData = null;
String password = "******";
try {
FileInputStream is = new FileInputStream("C:/Users/girgich/keystore.jks");
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(is, password.toCharArray());
String alias = "mykey";
Key key = keystore.getKey(alias, password.toCharArray());
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
decryptedData = cipher.doFinal(encryptedTextKey.getBytes());
System.out.println("Decrypted Key: " + decryptedData);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Using the Google Cloud IAM api, i'm generating a PKCS12 private key for a service account. By default, the key password is "notasecret". How can I programmatically change it to something more secure?
import com.google.api.services.iam.v1.model.*;
Iam iam = googleIamClient(googleAppCredentials()); // helper method
String name = "projects/" + projectId + "/serviceAccounts/" + serviceAccountEmail;
CreateServiceAccountKeyRequest req = new CreateServiceAccountKeyRequest();
req.setPrivateKeyType("TYPE_PKCS12_FILE");
ServiceAccountKey key = iam.projects().serviceAccounts().keys().create(name, req).execute();
// equivalent to: byte[] privateKeyByteData = Base64.getDecoder().decode(serviceAccountKey.getPrivateKeyData());
byte[] privateKeyData = key.decodePrivateKeyData();
// what now?
This will change the password for the Google Cloud IAM PKCS12 certificate, and can probably be generalized to others:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.cert.*;
public byte[] changePKCS12KeyPassword(byte[] privateKeyData, String oldPassword, String newPassword) {
try {
KeyStore newKs = KeyStore.getInstance("PKCS12");
newKs.load(null, null);
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new ByteArrayInputStream(privateKeyData), oldPassword.toCharArray());
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
Key privateKey = ks.getKey(alias, oldPassword.toCharArray());
java.security.cert.Certificate[] certificateChain = ks.getCertificateChain(alias);
newKs.setKeyEntry(alias, privateKey, newPassword.toCharArray(), certificateChain);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
newKs.store(baos, newPassword.toCharArray());
return baos.toByteArray();
} catch (KeyStoreException
| CertificateException
| NoSuchAlgorithmException
| UnrecoverableKeyException
| IOException e) {
throw new RuntimeException(e);
}
}
I tried to encrypt and decrypt a .txt file. The encryption worked fine but when I decrypt it the .txt file is empty. Here is my code:
package crypto;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class MyCrypto
{
SecretKeySpec key;
Cipher cipher;
byte[] iv = {0,0,0,0,0,0,0,0};
IvParameterSpec ivspec = new IvParameterSpec(iv);
MyCrypto() throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException
{
key =new SecretKeySpec("22042016".getBytes(), "DES");
cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
}
public void encrypt(File file) throws InvalidKeyException, IOException
{
cipher.init(Cipher.ENCRYPT_MODE, key);
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file);
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
byte[] block = new byte[8];
int i;
while ((i = fis.read(block)) != -1) {
cos.write(block, 0, i);
}
cos.close();
fis.close();
}
public void decrypt(File file) throws IOException, InvalidKeyException, InvalidAlgorithmParameterException
{
cipher.init(Cipher.DECRYPT_MODE, key, ivspec);
FileInputStream fis = new FileInputStream(file);
CipherInputStream cis = new CipherInputStream(fis, cipher);
FileOutputStream fos = new FileOutputStream(file);
byte[] block = new byte[8];
int i;
while ((i = cis.read(block)) != -1) {
fos.write(block, 0, i);
}
cis.close();
fos.close();
}
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException
{
MyCrypto crypto = new MyCrypto();
File cryptoFile = new File(".../crypto.txt");
crypto.encrypt(cryptoFile);
crypto.decrypt(cryptoFile);
}
}
I know that DES isn't very safe. But it's just for my trying to mess around with de- and encryption.
Try replacing the code in your decrypt method with this:
// write decrypted bytes
fos.write(cipher.doFinal(Files.readAllBytes(file.toPath())));
// close the output file
fos.flush();
fos.close();
I need to sign a large file in java, using a MakeCert.exe (from from the Windows SDK 8.) generated DSA private key.
makecert.exe -sy 13 -sv C:\SignFile3\dsasign.pvk -pe -r -n "CN=LGS CA" C:\SignFile3\dsasign.crt
The pvk is the private key I want to sign with.
Next my complete Java code:
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.DataInputStream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.security.*;
import java.security.spec.*;
class GenSig {
public static final String PRIVATE_KEY_FILE = "dsasign.pvk";
public static byte[] fullyReadFile(File file) throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream(file));
byte[] bytesOfFile = new byte[(int) file.length()];
dis.readFully(bytesOfFile);
dis.close();
return bytesOfFile;
}
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: GenSig nameOfFileToSign");
}
else {
try {
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
File myfile = new File(PRIVATE_KEY_FILE);
byte[] decodedprivatekey = fullyReadFile(myfile);
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(decodedprivatekey);
PrivateKey priv = keyFactory.generatePrivate(priKeySpec);
Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
dsa.initSign(priv);
/* Update and sign the data */
FileInputStream fis = new FileInputStream(args[0]);
BufferedInputStream bufin = new BufferedInputStream(fis);
byte[] buffer = new byte[1024];
int len;
while (bufin.available() != 0) {
len = bufin.read(buffer);
dsa.update(buffer, 0, len);
};
bufin.close();
/* Now that all the data to be signed has been read in, generate a signature for it */
byte[] realSig = dsa.sign();
/* Save the signature in a file */
FileOutputStream sigfos = new FileOutputStream("signature.binary");
sigfos.write(realSig);
sigfos.close();
}
}
catch (Exception e) {
System.err.println("Caught exception " + e.toString());
}
};
}
The error I get running it is:
Caught exception java.security.spec.InvalidKeySpecException: Inappropriate key specification: IOException : DerInputStream.getLength(): lengthTag=113, too big.
For over a week, I've been using this to implement a RSA secured communication with my server that is in python.
However, I can not for the life of me figure out the proper imports for all the jars.
I have included all the jars found on bouncy castles website and still no dice!
I read that they moved stuff around. If this code is old or broken, what other implementation of RSA with pkcs1 padding is put there?
EDIT:
pub key is in a file named key.pub. how do I read that file in to be used as the key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2B0wo+QJ6tCqeyTzhZ3
AtPLgAHEQ/fRYDcR0BkQ+lXEhD277P2fPZwla5AW6szqsjR1olkZEF7IuoI27Hxm
tQHJU0ROhrzstHgK42emz5Ya3BWcm+oq5pLDZnsNDnNlrPncaCT7gHQQJn3YjH8q
aibtB1WCoy7ZJ127QxoKoLfeonBDtt7Qw6P5iXE57IbQ63oLq1EaYUfg8ZpADvJF
b2H3MASJSSDrSDgrtCcKAUYuu3cZw16XShuKCNb5QLsj3tR0QC++7qjM3VcG311K
7gHVjB6zybw+5vX2UWTgZuL6WVtCvRK+WY7nhL3cc5fmXZhkW1Jbx6wLPK3K/JcR
NQIDAQAB
-----END PUBLIC KEY-----
EDIT 2: Adding Broken Code based on an answer
package Main;
import org.bouncycastle.util.encoders.Base64;
import javax.crypto.Cipher;
import javax.xml.bind.DatatypeConverter;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.X509EncodedKeySpec;
public class EncDecRSA {
public static byte[] pemToDer(String pemKey) throws GeneralSecurityException {
String[] parts = pemKey.split("-----");
return DatatypeConverter.parseBase64Binary(parts[parts.length / 2]);
}
public static PublicKey derToPublicKey(byte[] asn1key) throws GeneralSecurityException {
X509EncodedKeySpec spec = new X509EncodedKeySpec(asn1key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
return keyFactory.generatePublic(spec);
}
public static byte[] encrypt(PublicKey publicKey, String text) throws GeneralSecurityException {
Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding", "BC");//PKCS1-OAEP
rsa.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipher = rsa.doFinal(text.getBytes());
String s = new String(cipher);
System.out.print(s);
// return cipher;
// return Base64.encode(rsa.doFinal(text.getBytes()));
cipher = Base64.encode(cipher);
return cipher;
}
static String readFile(String path)
throws IOException
{
String line = null;
BufferedReader br = new BufferedReader(new FileReader(path));
try {
StringBuilder sb = new StringBuilder();
line = br.readLine();
while (line != null) {
sb.append(line);
sb.append("\n");
line = br.readLine();
}
return sb.toString();
} finally {
br.close();
}
}
public static void main(String[] args) throws IOException, GeneralSecurityException {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
System.out.println("Working Directory = " +
System.getProperty("user.dir"));
String publicKey = readFile("key.public");
byte[] pem = pemToDer(publicKey);
PublicKey myKey = derToPublicKey(pem);
String sendMessage = "{'vid_hash': '917ef7e7be4a84e279b74a257953307f1cff4a2e3d221e363ead528c6b556edb', 'state': 'ballot_response', 'userInfo': {'ssn': '700-33-6870', 'pin': '1234', 'vid': '265jMeges'}}";
byte[] encryptedDATA = encrypt(myKey, sendMessage);
Socket smtpSocket = null;
DataOutputStream os = null;
DataInputStream is = null;
try {
smtpSocket = new Socket("192.168.1.124", 9999);
os = new DataOutputStream(smtpSocket.getOutputStream());
is = new DataInputStream(smtpSocket.getInputStream());
} catch (UnknownHostException e) {
System.err.println("Don't know about host: hostname");
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: hostname");
}
if (smtpSocket != null && os != null && is != null) {
try {
System.out.println("sending message");
os.writeBytes(encryptedDATA+"\n");
os.close();
is.close();
smtpSocket.close();
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
}
Which has the following error:
Here is the bit of python code that does that:
def _decrypt_RSA(self, private_key_loc, package):
'''
param: public_key_loc Path to your private key
param: package String to be decrypted
return decrypted string
'''
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from base64 import b64decode
key = open('key.private', "r").read()
rsakey = RSA.importKey(key)
rsakey = PKCS1_OAEP.new(rsakey)
decrypted = rsakey.decrypt(package)
# decrypted = rsakey.decrypt(b64decode(package))
return decrypted
Lastly:
Is this padding scheme with PKCS1-OAEP.
That is a major requirement for this to work.
Note that I have tried it with both base64 encode and without
This example is for SpongyCastle - Android repackage of BouncyCastle. They differ as you noticed. However, making encryption in Java is as simple as this
Convert Base64 encoded key string to ASN.1 DER encoded byte array
public static byte[] pemToDer(String pemKey) throws GeneralSecurityException {
String[] parts = pemKey.split("-----");
return DatatypeConverter.parseBase64Binary(parts[parts.length / 2]);
}
Convert ASN.1 DER encoded public key to PublicKey object
public static PublicKey derToPublicKey(byte[] asn1key) throws GeneralSecurityException {
X509EncodedKeySpec spec = new X509EncodedKeySpec(asn1key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
return keyFactory.generatePublic(spec);
}
Encrypt data
public static byte[] encrypt(PublicKey publicKey, String text) throws GeneralSecurityException {
Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding", "BC");
rsa.init(Cipher.ENCRYPT_MODE, publicKey);
return rsa.doFinal(text.getBytes());
}
bcprov-jdk15on-150.jar is the only jar needed.