I am working on a feature which require Aes encrypted (AES/CBC/PKCS5padding) cipher text to be sent from client to server which has ASP.Net in backend.
I've a decryption function on the server side as below :
public static string Decrypt(string inputBase64, string passphrase = null)
{
byte[] key, iv = new byte[0];
byte[] base64data = Convert.FromBase64String(inputBase64);
byte[] passphrasedata = RawBytesFromString(passphrase);
byte[] currentHash = new byte[0];
SHA256Managed hash = new SHA256Managed();
currentHash = hash.ComputeHash(passphrasedata);
return DecryptStringFromBytes(base64data, currentHash, null);
}
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
//if (IV == null || IV.Length <= 0)
// throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (var cipher = new RijndaelManaged())
{
cipher.Key = Key;
cipher.IV = new byte[16];
//cipher.Mode = CipherMode.CBC;
//cipher.Padding = PaddingMode.PKCS7;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = cipher.CreateDecryptor(Key, cipher.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
var bytes = default(byte[]);
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
bytes = srDecrypt.CurrentEncoding.GetBytes(srDecrypt.ReadToEnd());
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
//aintext = srDecrypt.ReadToEnd();
}
plaintext = ASCIIEncoding.UTF8.GetString(bytes, 0, bytes.Count());
}
}
}
return plaintext;
}
I want to implement an angularjs alternative to the following android code :
public static String Encrypt(String input, String passphrase)
{
if (input.equalsIgnoreCase("") || passphrase.equalsIgnoreCase(""))
return "";
else
{
byte[] key, iv;
byte[] passphrasedata = null;
try
{
passphrasedata = passphrase.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e1)
{
e1.printStackTrace();
}
byte[] currentHash = new byte[0];
MessageDigest md = null;
try
{
md = MessageDigest.getInstance("SHA-256");
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
currentHash = md.digest(passphrasedata);
iv = new byte[16];
return Base64.encodeToString(EncryptStringToBytes(input, currentHash, iv), Base64.NO_WRAP);
}
}
static byte[] EncryptStringToBytes(String plainText, byte[] Key, byte[] IV)
{
if (plainText == null || plainText.length() <= 0)
{
Log.e("error", "plain text empty");
}
if (Key == null || Key.length <= 0)
{
Log.e("error", "key is empty");
}
if (IV == null || IV.length <= 0)
{
Log.e("error", "IV key empty");
}
byte[] encrypted;
try
{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec myKey = new SecretKeySpec(Key, "AES");
IvParameterSpec IVKey = new IvParameterSpec(IV);
cipher.init(Cipher.ENCRYPT_MODE, myKey, IVKey);
encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
return encrypted;
}
catch (InvalidKeyException e)
{
e.printStackTrace();
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (NoSuchPaddingException e)
{
e.printStackTrace();
}
catch (InvalidAlgorithmParameterException e)
{
e.printStackTrace();
}
catch (IllegalBlockSizeException e)
{
e.printStackTrace();
}
catch (BadPaddingException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
return null;
}
The Android code above is working fine. I want to implement the same encryption logic at AngularJs.
I've included CryptoJS library for SHA-256 and AES cipher calculation. Here is the code which I've implemented.
var password = '12345678';
var passwordHash = CryptoJS.SHA256(password).toString(CryptoJS.enc.Latin1);
var iv = CryptoJS.enc.Hex.parse('0000000000000000');
var cipher = CryptoJS.AES.encrypt(plaintext,passwordHash,{
iv: iv,
mode: CryptoJS.mode.CBC,
keySize: 256/32,
padding: CryptoJS.pad.Pkcs7
});
cipherText = cipher.ciphertext.toString(CryptoJS.enc.Base64);
The problem is that, the encoded string cannot be decrypted back to its previous form. I think there is some mismatch in the encryption logic in the client side and decryption logic on the server side.
When I pass the CryptoJS encrypted cipher to java decryption function, it shows errors:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
or sometimes:
javax.crypto.BadPaddingException: Given final block not properly padded
Thanks guys!!!, I got it working with the following code.
function hash (){
return CryptoJS.SHA256(password);
}
var cipher = (function(plaintext, password) {
passwordHash = hash(password);
var iv = CryptoJS.enc.Hex.parse('0000000000000000');
var cipher = CryptoJS.AES.encrypt(plaintext, passwordHash, {
iv: iv,
mode: CryptoJS.mode.CBC,
keySize: 256 / 32,
padding: CryptoJS.pad.Pkcs7
});
return cipher;
})(plaintext, password);
cipherBase64 = cipher.ciphertext.toString().hex2a().base64Encode();
Related
I encrypt data in android phone using AES GCM mode and sent it to java application in windows
The cipher text is created and received successfully
at decryption process an exception appeared(Tag miss match)
I tried to remove associated data update
I tried to set the provider to SunJCE
The code works great between java desktop applications but the error appears when use encryption decryption process between android and java
I use openjdk1.8
public static byte[] gcmMode(int gcmCipherMode, byte[] aadHeader,char[] password, byte[] inputBytes) {
byte[] outputBytes = new byte[0];
byte[] salt;
byte[] iv;
byte[] res;
SecretKeySpec ks;
try {
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
switch (gcmCipherMode) {
case Cipher.ENCRYPT_MODE:
salt = new byte[16]; random.nextBytes(salt);
iv = new byte[12]; random.nextBytes(iv);
res = salt(password, salt);
ks = new SecretKeySpec(res, "AES");
c.init(Cipher.ENCRYPT_MODE, ks, new GCMParameterSpec(128, iv));
if (aadHeader != null) {
c.updateAAD(aadHeader);
}
outputBytes = arrayByteConcatenate(salt, iv);
outputBytes = arrayByteConcatenate(outputBytes, c.doFinal(inputBytes));
break;
case Cipher.DECRYPT_MODE:
if (inputBytes.length > 44) {
salt = arrayByteSplit(inputBytes, 0, 16);
iv = arrayByteSplit(inputBytes, 16, 28);
res = salt(password, salt);
ks = new SecretKeySpec(res, "AES");
c.init(Cipher.DECRYPT_MODE, ks, new GCMParameterSpec(128, iv));
if (aadHeader != null) {
c.updateAAD(aadHeader);
}
// Return our Decrypted String
outputBytes = c.doFinal(arrayByteSplit(inputBytes, 28, inputBytes.length));
}else{
System.out.println("Wrong cipher");
}
break;
default:
System.out.println("UnKnown");
break;
}
} catch (NoSuchAlgorithmException | NoSuchPaddingException
| InvalidKeyException | IllegalBlockSizeException
| BadPaddingException | InvalidParameterException
| InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return outputBytes;
}
static byte[] salt (char[] password, byte[] salt) {
SecretKeyFactory skf = null;
byte[] res = new byte[0];
try {
skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(password, salt, 100000, 128);
SecretKey key = skf.generateSecret(spec);
res = key.getEncoded();
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
e.printStackTrace();
}
return res;
}
Error
javax.crypto.AEADBadTagException: Tag mismatch!
at com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:578)
at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1116)
at com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1053)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at javax.crypto.Cipher.doFinal(Cipher.java:2164)
at algorithm.encryption.AESencryption.gcmMode(AESencryption.java:91)
at ServerWorker.handleAuthentication(ServerWorker.java:97)
at ServerWorker.startMessageReader(ServerWorker.java:67)
at ServerWorker.handleClientSocket(ServerWorker.java:44)
at ServerWorker.run(ServerWorker.java:36)
I was trying to do encryption of videos and pdf. After i get the stream of each file, i divided into buffers, then i encrypt each one and combine all buffers into one encrypted file.
For encryption everything works fine but when i am trying to decrypt the file by the same way I am getting error at doFinal which is
{BadPaddingException : pad block corrupted
BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:739)}
here is the code I am testing
Encryption
public static byte[] encodeFile(byte[] key, byte[] fileData) throws Exception
{
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(fileData);
return encrypted;
}
Decryption
public static byte[] decodeFile(byte[] key, byte[] fileData)
{
byte[] decrypted=new byte[0];
try {
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
decrypted= cipher.doFinal(fileData);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
return decrypted;
}
Generate key
public static byte[] generateKey(String password) throws Exception
{
byte[] keyStart = password.getBytes("UTF-8");
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
sr.setSeed(keyStart);
kgen.init(256, sr);
SecretKey skey = kgen.generateKey();
return skey.getEncoded();
}
here is how i decrypt the file
public void decryptStream(String filePath) {
String outPath = Environment.getExternalStorageDirectory().toString() + "/" + fileName + "de" + "." + fileExtention;
filePath += "_secured." + fileExtention;
byte[] data = new byte[1024];
byte[] decryptData;
File file = new File((filePath));
File deFile = new File(outPath);
InputStream inputStream = null;
try {
inputStream = FileUtils.openInputStream(file);
} catch (IOException e) {
e.printStackTrace();
}
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream((new FileOutputStream(deFile)));
while ((inputStream.read(data)) != -1) {
decryptData = decryptByteArray(data);
bos.write(decryptData);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private byte[] decryptByteArray(byte[] input) {
Encryption e=new Encryption();
byte[]decryptedBytes = new byte[0];
try {
byte[] yourKey = e.generateKey("password");
decryptedBytes = e.decodeFile(yourKey, input);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (Exception e1) {
e1.printStackTrace();
}
return decryptedBytes;
}
The problem is most likely here:
while ((inputStream.read(data)) != -1) {
decryptData = decryptByteArray(data);
bos.write(decryptData);
}
When you read a file that is not a multiple of 1024 bytes long, the last read will not completely fill the byte array but you pass the whole array into decryptByteArray.
Also note, that there is no guarantee that read will fill the array completely even for intermediate reads. Always check the return value which gives the number of bytes actually read.
The question does not show how the encryption is done. If padding is used in the cipher, each encryption of a 1024 byte chunk will be longer than 1024 bytes (because of the added padding block). For decryption the whole ciphertext (including the padding) must be processed in one go. Just using the first 1024 bytes will lead to the BadPaddingException.
I have an encryption/decryption algorithm and I'm trying to encrypt some special characters to send to the server from android, but it is throwing an exception:
java.lang.Exception: [encrypt] error:0607F08A:digital envelope routines:EVP_EncryptFinal_ex:data not multiple of block length
Normal Latin characters are encrypted/decrypted fine, but special characters aren't.
Here is my code:
public class MCrypt {
private String iv = "fedcba9876543210";//Dummy iv (CHANGE IT!)
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
private String SecretKey = "0123456789abcdef";//Dummy secretKey (CHANGE IT!)
public MCrypt()
{
ivspec = new IvParameterSpec(iv.getBytes());
keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/NoPadding");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public byte[] encrypt(String text) throws Exception
{
//if(text == null || text.length() == 0)
// throw new Exception("Empty string");
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(padString(text).getBytes());
} catch (Exception e)
{
throw new Exception("[encrypt] " + e.getMessage());
}
return encrypted;
}
public byte[] decrypt(String code) throws Exception
{
if(code == null || code.length() == 0)
throw new Exception("Empty string");
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e)
{
throw new Exception("[decrypt] " + e.getMessage());
}
return decrypted;
}
public static String bytesToHex(byte[] data)
{
if (data==null)
{
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++) {
if ((data[i]&0xFF)<16)
str = str + "0" + Integer.toHexString(data[i]&0xFF);
else
str = str + Integer.toHexString(data[i]&0xFF);
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str==null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i=0; i<len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
}
return buffer;
}
}
private static String padString(String source)
{
char paddingChar = ' ';
int size = 32;
int x = source.length() % size;
int padLength = size - x;
for (int i = 0; i < padLength; i++)
{
source += paddingChar;
}
return source;
}
}
Does anyone know what the problem here is?
Thanks!
Change this line:
cipher = Cipher.getInstance("AES/CBC/NoPadding");
To
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
From this Blog
Change this line :
cipher = Cipher.getInstance("AES/CBC/NoPadding"); //this may be not decrypt full plaintext.
To:
cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); // use this for descrypt full plain text without lost.
I have a PHP servor which decrypt data in 3DES with the CFB Mode
I encrypt in PHP :
$montant = "500";
$message_crypte = mcrypt_encrypt(MCRYPT_3DES, "N4y1FRDRJ7wn7eJNnWaahCIS", $montant, ,CRYPT_MODE_CFB, "NCNPJDcR");
$montant = base64_encode($message_crypte);
This script in PHP is OK with other system.
And I want to encrypt in Java :
public class CryptData {
private KeySpec keySpec;
private SecretKey key;
private IvParameterSpec iv;
public CryptData(String keyString, String ivString) {
try {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest(Base64
.decodeBase64(keyString.getBytes("ISO-8859-1")));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
//keySpec = new DESedeKeySpec(keyBytes);
keySpec = new DESedeKeySpec(keyString.getBytes());
key = SecretKeyFactory.getInstance("DESede")
.generateSecret(keySpec);
iv = new IvParameterSpec(ivString.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
public String encrypt(String value) {
try {
Cipher ecipher = Cipher.getInstance("DESede/CFB/NoPadding");
//"SunJCE");
ecipher.init(Cipher.ENCRYPT_MODE, key, iv);
if (value == null)
return null;
// Encode the string into bytes using utf-8
byte[] valeur = value.getBytes("ISO-8859-1");
//byte[] utf8 = value.getBytes();
// Encrypt
byte[] enc = ecipher.doFinal(valeur);
// Encode bytes to base64 to get a string
return new String(Base64.encodeBase64(enc), "ISO-8859-1");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
I have not the same result in PHP and in Java
How modify Java treatment to obtain the same result as PHP?
The answer is:
Cipher ecipher = Cipher.getInstance("DESede/CFB8/NoPadding");
I need to use "CFB8"
I am working on AES algorithm, and I have this exception which I couldn't solve.
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
the exception happens in the decryption part.
I initialize the key in a different place from where the decryption algorithm is
KeyGenerator kgen = KeyGenerator.getInstance("AES");//key generation for AES
kgen.init(128); // 192 and 256 bits may not be available
then I pass it with the cipher text which I read from file to the following method
public String decrypt(String message, SecretKey skey) {
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
Cipher cipher;
byte[] original = null;
try {
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
System.out.println("Original string: "
+ message);
original = cipher.doFinal(message.trim().getBytes()); //here where I got the exception
String originalString = new String(original);
}
//catches
EDIT
here's the encryption method.
public String encrypt(String message, SecretKey skey) {
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
Cipher cipher;
byte[] encrypted = null;
try {
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encrypted = cipher.doFinal(message.getBytes());
System.out.println("raw is " + encrypted);
} catches
return asHex(encrypted);
}
and here's the asHex method
public static String asHex(byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) {
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
Here's where I read the cipher text form the file
static public String readFile(String filePath) {
StringBuilder file = new StringBuilder();
String line = null;
try {
FileReader reader = new FileReader(filePath);
BufferedReader br = new BufferedReader(reader);
if (br != null) {
line = br.readLine();
while (line != null) {
file.append(line);
// System.out.println("line is " + line);
line = br.readLine();
}
}
br.close();
reader.close();
} catch (IOException ex) {
Logger.getLogger(FileManagement.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("line is " + file.toString());
return String.valueOf(file);
}
can someone help?
Ok, so the problem is that you are converting the encrypted bytes to a hex string (using the asHex method) but are not converting the hex string back to a byte array correctly for decryption. You can't use getBytes.
You can use the following method to convert a hex string to a byte array:
public static byte[] fromHexString(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
and then change your decrypt method to use:
original = cipher.doFinal(fromHexString(message));
I did have a Bad Padding Exception and have not been able to find on the internet a solution to my problem. Since I found it after some hard-working hours, I give it here.
My problem was, I was reading a file on my hard drive, and encrypting it through a buffer, always calling the doFinal() method instead of update() method. So when decrypting it, I had padding errors
input = new FileInputStream(file);
output = new FileOutputStream(newFile);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, mySecretKey);
byte[] buf = new byte[1024];
count = input.read(buf);
while (count >= 0) {
output.write(cipher.update(buf, 0, count)); // HERE I WAS DOING doFinal() method
count = input.read(buf);
}
output.write(cipher.doFinal()); // AND I DID NOT HAD THIS LINE BEFORE
output.flush();
And when decrypting, with the same method, but with a Cipher init with DECRYPT_MODE
input = new FileInputStream(file);
output = new FileOutputStream(newFile);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, mySecretKey);
byte[] buf = new byte[1024];
count = input.read(buf);
while (count >= 0) {
output.write(cipher.update(buf, 0, count)); // HERE I WAS DOING doFinal() method
//AND HERE WAS THE BadPaddingExceotion -- the first pass in the while structure
count = input.read(buf);
}
output.write(cipher.doFinal()); // AND I DID NOT HAD THIS LINE BEFORE
output.flush();
With the code written, I no longer have any BadPaddingException.
I may precise that this exception only appears when the original clear file length (obtained through file.length()) is bigger than the buffer. Else, we do not need to pass several times in the while structure, and we can encrypt in one pass with a doFinal() call. That justify the random character of the exception following the size of the file you try to encrypt.
I hope you had a good reading!
I guess the expression message.trim().getBytes() does not return the same bytes which are generated when you encrypted the message. Specially the trim() method could delete the bytes which were added as padding in the encrypted message.
Verify that both the returned array of the doFinal() method during the encryption and the returned array of message.trim().getBytes():
got the same number of bytes (array length)
got the same bytes in the array
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(512);
KeyPair rsaKeyPair = kpg.genKeyPair();
byte[] txt = "This is a secret message.".getBytes();
System.out.println("Original clear message: " + new String(txt));
// encrypt
Cipher cipher;
try
{
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, rsaKeyPair.getPublic());
txt = cipher.doFinal(txt);
}
catch (Throwable e)
{
e.printStackTrace();
return;
}
System.out.println("Encrypted message: " + new String(txt));
// decrypt
try
{
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, rsaKeyPair.getPrivate());
txt = cipher.doFinal(txt);
}
catch (Throwable e)
{
e.printStackTrace();
return;
}
System.out.println("Decrypted message: " + new String(txt));
Here is a solution I was able to piece together using a jks keystore with RSA encryption
import javax.crypto.Cipher;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.cert.Certificate;
public class Main {
public static void main(String[] args) {
byte[] txt = "This is a secret message for your own eyes only".getBytes();
byte[] encText;
try{
// Load the keystore
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
char[] password = "keystorePassword".toCharArray();
java.io.FileInputStream fis = new java.io.FileInputStream("/path/to/keystore/myKeyStore.jks");
ks.load(fis, password);
fis.close();
Key rsakey = ks.getKey("mykeyalias", password);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// Encrypt
Certificate cert = ks.getCertificate("mykeyalias");
try
{
cipher.init(Cipher.ENCRYPT_MODE, cert.getPublicKey());
encText = cipher.doFinal(txt);
System.out.println(encText.toString());
}
catch (Throwable e)
{
e.printStackTrace();
return;
}
// Decrypt
cipher.init(Cipher.DECRYPT_MODE, rsakey);
String decrypted = new String(cipher.doFinal(encText));
System.out.println(decrypted);
} catch (Exception e) {
System.out.println("error" + e);
}
}