Java tutorial
package org.votingsystem.signature.util; import org.bouncycastle.cms.*; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.mail.smime.SMIMEEnveloped; import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; import org.bouncycastle.mail.smime.SMIMEUtil; import org.bouncycastle.util.Strings; import org.votingsystem.model.ResponseVS; import org.votingsystem.signature.smime.SMIMEMessage; import org.votingsystem.throwable.ExceptionVS; import org.votingsystem.util.ContextVS; import org.votingsystem.util.FileUtils; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import javax.mail.BodyPart; import javax.mail.Header; import javax.mail.Multipart; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import java.io.*; import java.security.*; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidParameterSpecException; import java.security.spec.KeySpec; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; /** * License: https://github.com/votingsystem/votingsystem/wiki/Licencia * * What is triple-DES -> http://www.rsa.com/rsalabs/node.asp?id=2231 * http://www.bouncycastle.org/wiki/display/JA1/Frequently+Asked+Questions */ public class Encryptor { private static Logger log = Logger.getLogger(Encryptor.class.getSimpleName()); private static final int ITERATION_COUNT = 1024; private static final int KEY_LENGTH = 128; // 192 and 256 bits may not be available private Recipient recipient; private RecipientId recipientId; private PrivateKey privateKey; public Encryptor(X509Certificate localCert, PrivateKey localPrivateKey) { this.privateKey = localPrivateKey; recipientId = new JceKeyTransRecipientId(localCert); recipient = new JceKeyTransEnvelopedRecipient(localPrivateKey).setProvider(ContextVS.PROVIDER); } public byte[] encryptMessage(byte[] bytesToEncrypt, PublicKey publicKey) throws Exception { MimeBodyPart mimeMessage = new MimeBodyPart(); mimeMessage.setText(new String(bytesToEncrypt)); //mimeMessage.setSentDate(new Date());// set the Date: header SMIMEEnvelopedGenerator encryptor = new SMIMEEnvelopedGenerator(); encryptor.addRecipientInfoGenerator( new JceKeyTransRecipientInfoGenerator("".getBytes(), publicKey).setProvider(ContextVS.PROVIDER)); /* Encrypt the message */ MimeBodyPart encryptedPart = encryptor.generate(mimeMessage, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(ContextVS.PROVIDER) .build()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); encryptedPart.writeTo(baos); baos.close(); return baos.toByteArray(); } public static byte[] encryptMessage(byte[] text, X509Certificate receiverCert, Header... headers) throws Exception { MimeMessage mimeMessage = new MimeMessage(ContextVS.MAIL_SESSION); mimeMessage.setText(new String(text, "UTF-8")); // set the Date: header //mimeMessage.setSentDate(new Date()); if (headers != null) { for (Header header : headers) { if (header != null) mimeMessage.setHeader(header.getName(), header.getValue()); } } SMIMEEnvelopedGenerator encryptor = new SMIMEEnvelopedGenerator(); encryptor.addRecipientInfoGenerator( new JceKeyTransRecipientInfoGenerator(receiverCert).setProvider(ContextVS.PROVIDER)); /* Encrypt the message */ MimeBodyPart encryptedPart = encryptor.generate(mimeMessage, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(ContextVS.PROVIDER) .build()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); encryptedPart.writeTo(baos); baos.close(); return baos.toByteArray(); } /** * Method to decrypt files attached to SMIME (not signed) messages */ public byte[] decryptMessage(byte[] encryptedFile) throws Exception { MimeMessage msg = new MimeMessage(ContextVS.MAIL_SESSION, new ByteArrayInputStream(encryptedFile)); SMIMEEnveloped smimeEnveloped = new SMIMEEnveloped(msg); RecipientInformationStore recipients = smimeEnveloped.getRecipientInfos(); RecipientInformation recipientInfo = recipients.get(recipientId); RecipientId messageRecipientId = null; if (recipientInfo != null && recipientInfo.getRID() != null) { messageRecipientId = recipientInfo.getRID(); log.info("messageRecipientId.getSerialNumber(): " + messageRecipientId.getSerialNumber()); } else throw new ExceptionVS("No message found for recipientId: " + recipientId.getSerialNumber()); MimeBodyPart mimeMessage = SMIMEUtil.toMimeBodyPart(recipientInfo.getContent(recipient)); /*ByteArrayOutputStream baos = new ByteArrayOutputStream(); mimeMessage.writeTo(baos) log.info(" mimeMessage: ${new String(baos.toByteArray())}")*/ Object messageContent = mimeMessage.getContent(); byte[] messageContentBytes = null; //log.info(" messageContent class: ${messageContent?.getClass()}") if (messageContent instanceof MimeMultipart) { MimeMultipart mimeMultipart = (MimeMultipart) messageContent; BodyPart bodyPart = mimeMultipart.getBodyPart(0); InputStream stream = bodyPart.getInputStream(); ByteArrayOutputStream bodyPartOutputStream = new ByteArrayOutputStream(); byte[] buf = new byte[2048]; int len; while ((len = stream.read(buf)) > 0) { bodyPartOutputStream.write(buf, 0, len); } stream.close(); bodyPartOutputStream.close(); messageContentBytes = bodyPartOutputStream.toByteArray(); } else if (messageContent instanceof byte[]) { messageContentBytes = (byte[]) messageContent; } else if (messageContent instanceof String) { //log.info(" messageContent: ${messageContent}") String[] votingHeaders = mimeMessage.getHeader("votingSystemMessageType"); String encodedContentType = null; if (votingHeaders != null && votingHeaders.length > 0) encodedContentType = mimeMessage.getHeader("votingSystemMessageType")[0]; if (encodedContentType != null) { if (ContextVS.BASE64_ENCODED_CONTENT_TYPE.equals(encodedContentType)) { messageContentBytes = Base64.getDecoder().decode((String) messageContent); } else log.log(Level.SEVERE, "### unknown votingSystemMessageType: " + encodedContentType); } else messageContentBytes = messageContent.toString().getBytes(); } return messageContentBytes; } /** * Method to encrypt SMIME signed messages */ public ResponseVS encryptSMIME(byte[] bytesToEncrypt, X509Certificate receiverCert) throws Exception { //If the message isn't recreated there can be problems with multipart boundaries. TODO SMIMEMessage msgToEncrypt = new SMIMEMessage(new ByteArrayInputStream(bytesToEncrypt)); SMIMEEnvelopedGenerator encryptor = new SMIMEEnvelopedGenerator(); encryptor.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(receiverCert).setProvider("BC")); /* Encrypt the message */ MimeBodyPart encryptedPart = encryptor.generate(msgToEncrypt, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider("BC").build()); // Create a new MimeMessage that contains the encrypted and signed content /* Set all original MIME headers in the encrypted message */ Enumeration headers = msgToEncrypt.getAllHeaderLines(); while (headers.hasMoreElements()) { String headerLine = (String) headers.nextElement(); //log.info(" - headerLine: ${headerLine}"); /* * Make sure not to override any content-* headers from the * original message */ if (!Strings.toLowerCase(headerLine).startsWith("content-")) { encryptedPart.addHeaderLine(headerLine); } } /*SignerInformationStore signers = msgToEncrypt.getSmimeSigned().getSignerInfos(); Iterator<SignerInformation> it = signers.getSigners().iterator(); byte[] digestBytes = it.next().getContentDigest();//method can only be called after verify.*/ ByteArrayOutputStream baos = new ByteArrayOutputStream(); encryptedPart.writeTo(baos); return new ResponseVS(ResponseVS.SC_OK, baos.toByteArray()); } /** * Method to decrypt SMIME signed messages */ public ResponseVS decryptSMIME(byte[] encryptedMessageBytes) throws Exception { SMIMEMessage smimeMessageReq = null; MimeMessage msg = new MimeMessage(ContextVS.MAIL_SESSION, new ByteArrayInputStream(encryptedMessageBytes)); //String encryptedMessageBytesStr = new String(encryptedMessageBytes); //log.info("- decryptSMIME - encryptedMessageBytesStr: " + encryptedMessageBytesStr) SMIMEEnveloped smimeEnveloped = new SMIMEEnveloped(msg); RecipientInformationStore recipients = smimeEnveloped.getRecipientInfos(); RecipientInformation recipientInfo = recipients.get(recipientId); /*RecipientId recipientRID = null; if(recipient.getRID() != null) { recipientRID = recipient.getRID(); log.info(" -- recipientRID.getSerialNumber(): " + recipientRID.getSerialNumber()); if(recipient.getRID().getCertificate() != null) { log.info(" -- recipient: " + recipient.getRID().getCertificate().getSubjectDN().toString()); } else log.info(" -- recipient.getRID().getCertificate() NULL"); } else log.info(" -- getRID NULL"); MimeBodyPart res = SMIMEUtil.toMimeBodyPart( recipient.getContent(new JceKeyTransEnvelopedRecipient(serverPrivateKey).setProvider("BC")));*/ if (recipientInfo == null) { log.log(Level.SEVERE, "Expected recipientId.getSerialNumber(): " + recipientId.getSerialNumber()); Collection<RecipientInformation> recipientCollection = recipients.getRecipients(); for (RecipientInformation recipientInf : recipientCollection) { log.log(Level.SEVERE, "Encrypted document recipientId.getSerialNumber(): " + recipientInf.getRID().getSerialNumber()); } return new ResponseVS(ResponseVS.SC_ERROR_REQUEST, ContextVS.getMessage("encryptionRecipientErrorMsg")); } byte[] messageContentBytes = recipientInfo.getContent(recipient); //log.info(" ------- Message Contents: ${new String(messageContentBytes)}"); smimeMessageReq = new SMIMEMessage(new ByteArrayInputStream(messageContentBytes)); ResponseVS responseVS = new ResponseVS(ResponseVS.SC_OK); responseVS.setSMIME(smimeMessageReq); return responseVS; } public static byte[] encryptToCMS(byte[] dataToEncrypt, X509Certificate receptorCert) throws Exception { CMSEnvelopedDataStreamGenerator dataStreamGen = new CMSEnvelopedDataStreamGenerator(); dataStreamGen.addRecipientInfoGenerator( new JceKeyTransRecipientInfoGenerator(receptorCert).setProvider(ContextVS.PROVIDER)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = dataStreamGen.open(bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC) .setProvider(ContextVS.PROVIDER).build()); out.write(dataToEncrypt); out.close(); return Base64.getEncoder().encode(bOut.toByteArray()); } public static byte[] encryptToCMS(byte[] dataToEncrypt, PublicKey receptorPublicKey) throws Exception { CMSEnvelopedDataStreamGenerator dataStreamGen = new CMSEnvelopedDataStreamGenerator(); dataStreamGen .addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator("".getBytes(), receptorPublicKey) .setProvider(ContextVS.PROVIDER)); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = dataStreamGen.open(bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC) .setProvider(ContextVS.PROVIDER).build()); out.write(dataToEncrypt); out.close(); return Base64.getEncoder().encode(bOut.toByteArray()); } public byte[] decryptCMS(byte[] base64EncryptedData) throws Exception { byte[] cmsEncryptedData = Base64.getDecoder().decode(base64EncryptedData); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(cmsEncryptedData); RecipientInformationStore recipients = ep.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); byte[] result = null; if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation) it.next(); CMSTypedStream recData = recipient.getContentStream( new JceKeyTransEnvelopedRecipient(privateKey).setProvider(ContextVS.PROVIDER)); return FileUtils.getBytesFromStream(recData.getContentStream()); } return result; } public static byte[] decryptCMS(byte[] base64EncryptedData, PrivateKey privateKey) throws CMSException, IOException { //byte[] cmsEncryptedData = Base64.getDecoder().decode(base64EncryptedData); byte[] cmsEncryptedData = org.bouncycastle.util.encoders.Base64.decode(base64EncryptedData); CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(cmsEncryptedData); RecipientInformationStore recipients = ep.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); byte[] result = null; if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation) it.next(); //assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream( new JceKeyTransEnvelopedRecipient(privateKey).setProvider(ContextVS.PROVIDER)); return FileUtils.getBytesFromStream(recData.getContentStream()); } return result; } public static byte[] encryptSMIME(SMIMEMessage msgToEncrypt, X509Certificate receiverCert) throws Exception { /* Create the encryptor */ SMIMEEnvelopedGenerator encryptor = new SMIMEEnvelopedGenerator(); encryptor.addRecipientInfoGenerator( new JceKeyTransRecipientInfoGenerator(receiverCert).setProvider(ContextVS.PROVIDER)); /* Encrypt the message */ MimeBodyPart encryptedPart = encryptor.generate(msgToEncrypt, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(ContextVS.PROVIDER) .build()); /* Set all original MIME headers in the encrypted message */ Enumeration headers = msgToEncrypt.getAllHeaderLines(); while (headers.hasMoreElements()) { String headerLine = (String) headers.nextElement(); log.info("headerLine: " + headerLine); /* * Make sure not to override any content-* headers from the * original message */ if (!Strings.toLowerCase(headerLine).startsWith("content-")) { encryptedPart.addHeaderLine(headerLine); } } /*SignerInformationStore signers = msgToEncrypt.getSmimeSigned().getSignerInfos(); Iterator<SignerInformation> it = signers.getSigners().iterator(); byte[] digestBytes = it.next().getContentDigest();//method can only be called after verify.*/ ByteArrayOutputStream baos = new ByteArrayOutputStream(); encryptedPart.writeTo(baos); byte[] result = baos.toByteArray(); baos.close(); return result; } /** * Method to decrypt SMIME signed messages */ public static SMIMEMessage decryptSMIME(byte[] encryptedMessageBytes, PublicKey publicKey, PrivateKey receiverPrivateKey) throws Exception { InputStream inputStream = new ByteArrayInputStream( decryptMessage(encryptedMessageBytes, receiverPrivateKey)); return new SMIMEMessage(inputStream); } /** * helper method to decrypt SMIME signed messages */ public static byte[] decryptMessage(byte[] encryptedMessageBytes, PrivateKey receiverPrivateKey) throws Exception { log.info("decryptMessage(...) "); RecipientId recId = null; /*if(receiverCert != null) recId = new JceKeyTransRecipientId(receiverCert);*/ Recipient recipient = new JceKeyTransEnvelopedRecipient(receiverPrivateKey).setProvider(ContextVS.PROVIDER); MimeMessage msg = new MimeMessage(null, new ByteArrayInputStream(encryptedMessageBytes)); SMIMEEnveloped smimeEnveloped = new SMIMEEnveloped(msg); RecipientInformationStore recipients = smimeEnveloped.getRecipientInfos(); RecipientInformation recipientInfo = null; //if(recId != null) recipientInfo = recipients.get(recId); if (recipientInfo == null && recipients.getRecipients().size() == 1) { recipientInfo = (RecipientInformation) recipients.getRecipients().iterator().next(); } byte[] messageBytes = recipientInfo.getContent(recipient); return messageBytes; } public static byte[] encryptFile(File fileToEncrypt, X509Certificate receiverCert) throws Exception { log.info("encryptFile(...)"); MimeMessage mimeMessage = new MimeMessage(ContextVS.MAIL_SESSION); MimeBodyPart mimeBodyPart = new MimeBodyPart(); FileDataSource fds = new FileDataSource(fileToEncrypt); mimeBodyPart.setDataHandler(new DataHandler(fds)); mimeBodyPart.setFileName(fds.getName()); Multipart multipart = new MimeMultipart(); multipart.addBodyPart(mimeBodyPart); mimeMessage.setContent(multipart); // set the Date: header //mimeMessage.setSentDate(new Date()); SMIMEEnvelopedGenerator encryptor = new SMIMEEnvelopedGenerator(); encryptor.addRecipientInfoGenerator( new JceKeyTransRecipientInfoGenerator(receiverCert).setProvider(ContextVS.PROVIDER)); /* Encrypt the message */ MimeBodyPart encryptedPart = encryptor.generate(mimeMessage, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(ContextVS.PROVIDER) .build()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); encryptedPart.writeTo(baos); byte[] result = baos.toByteArray(); baos.close(); return result; } public static byte[] decryptCMSStream(PrivateKey privateKey, byte[] cmsEncryptedData) throws Exception { CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(cmsEncryptedData); RecipientInformationStore recipients = ep.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); byte[] result = null; if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation) it.next(); //assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); CMSTypedStream recData = recipient.getContentStream( new JceKeyTransEnvelopedRecipient(privateKey).setProvider(ContextVS.PROVIDER)); InputStream dataStream = recData.getContentStream(); ByteArrayOutputStream dataOut = new ByteArrayOutputStream(); byte[] buf = new byte[4096]; int len = 0; while ((len = dataStream.read(buf)) >= 0) { dataOut.write(buf, 0, len); } dataOut.close(); result = dataOut.toByteArray(); //assertEquals(true, Arrays.equals(data, dataOut.toByteArray())); } return result; } public static byte[] decryptFile(byte[] encryptedFile, PublicKey publicKey, PrivateKey receiverPrivateKey) throws Exception { RecipientId recId = new KeyTransRecipientId(publicKey.getEncoded()); Recipient recipient = new JceKeyTransEnvelopedRecipient(receiverPrivateKey).setProvider(ContextVS.PROVIDER); MimeMessage msg = new MimeMessage(null, new ByteArrayInputStream(encryptedFile)); SMIMEEnveloped smimeEnveloped = new SMIMEEnveloped(msg); RecipientInformationStore recipients = smimeEnveloped.getRecipientInfos(); RecipientInformation recipientInfo = null; recipientInfo = recipients.get(recId); if (recipientInfo == null && recipients.getRecipients().size() == 1) { recipientInfo = (RecipientInformation) recipients.getRecipients().iterator().next(); } RecipientId fileRecipientId = null; if (recipientInfo.getRID() != null) { fileRecipientId = recipientInfo.getRID(); } byte[] result = recipientInfo.getContent(recipient); return result; } public static EncryptedBundle pbeAES_Encrypt(String password, byte[] bytesToEncrypt) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, UnsupportedEncodingException, BadPaddingException, IllegalBlockSizeException { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); byte[] salt = KeyGeneratorVS.INSTANCE.getSalt(); KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH); SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secret); AlgorithmParameters params = cipher.getParameters(); byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV(); return new EncryptedBundle(cipher.doFinal(bytesToEncrypt), iv, salt); } public static byte[] pbeAES_Decrypt(String password, EncryptedBundle bundle) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); KeySpec spec = new PBEKeySpec(password.toCharArray(), bundle.salt, ITERATION_COUNT, KEY_LENGTH); SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(bundle.iv)); return cipher.doFinal(bundle.cipherText); } public static class EncryptedBundle { byte[] iv, cipherText, salt; public EncryptedBundle(byte[] cipherText, byte[] iv, byte[] salt) { this.iv = iv; this.cipherText = cipherText; this.salt = salt; } public byte[] getIV() { return iv; } public byte[] getCipherText() { return cipherText; } public byte[] getSalt() { return salt; } public Map<String, String> toMap() { Map result = new HashMap<>(); result.put("iv", Base64.getEncoder().encodeToString(iv)); result.put("salt", Base64.getEncoder().encodeToString(salt)); result.put("cipherText", Base64.getEncoder().encodeToString(cipherText)); return result; } public static EncryptedBundle parse(Map<String, String> jsonObject) { byte[] iv = Base64.getDecoder().decode(jsonObject.get("iv").getBytes()); byte[] cipherText = Base64.getDecoder().decode(jsonObject.get("cipherText").getBytes()); byte[] salt = Base64.getDecoder().decode(jsonObject.get("salt").getBytes()); return new EncryptedBundle(cipherText, iv, salt); } } /*public static String encryptAES(String messageToEncrypt, AESParams params) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, NoSuchProviderException { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, params.getKey(), params.getIV()); byte[] encryptedMessage = cipher.doFinal(messageToEncrypt.getBytes("UTF-8")); return new String(org.bouncycastle.util.encoders.Base64.encode(encryptedMessage)); } //decrypts base64 encoded AES message public static String decryptAES(String messageToDecrypt, AESParams params) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, params.getKey(), params.getIV()); byte[] encryptedMessageBytes = org.bouncycastle.util.encoders.Base64.decode(messageToDecrypt.getBytes()); byte[] decryptedBytes = cipher.doFinal(encryptedMessageBytes); return new String(decryptedBytes, "UTF8"); }*/ //BC provider to avoid key length restrictions on normal jvm public static String encryptAES(String messageToEncrypt, AESParams aesParams) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, InvalidCipherTextException { PaddedBufferedBlockCipher pbbc = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine())); KeyParameter keyParam = new KeyParameter(aesParams.getKey().getEncoded()); ParametersWithIV params = new ParametersWithIV(keyParam, aesParams.getIV().getIV()); pbbc.init(true, params); //to decrypt put param to false byte[] input = messageToEncrypt.getBytes("UTF-8"); byte[] output = new byte[pbbc.getOutputSize(input.length)]; int bytesWrittenOut = pbbc.processBytes(input, 0, input.length, output, 0); pbbc.doFinal(output, bytesWrittenOut); return new String(org.bouncycastle.util.encoders.Base64.encode(output)); } //BC provider to avoid key length restrictions on normal jvm public static String decryptAES(String messageToDecrypt, AESParams aesParams) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, InvalidCipherTextException { PaddedBufferedBlockCipher pbbc = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine())); KeyParameter keyParam = new KeyParameter(aesParams.getKey().getEncoded()); CipherParameters params = new ParametersWithIV(keyParam, aesParams.getIV().getIV()); pbbc.init(false, params); //to encrypt put param to true byte[] input = org.bouncycastle.util.encoders.Base64.decode(messageToDecrypt.getBytes("UTF-8")); byte[] output = new byte[pbbc.getOutputSize(input.length)]; int bytesWrittenOut = pbbc.processBytes(input, 0, input.length, output, 0); pbbc.doFinal(output, bytesWrittenOut); int i = output.length - 1; //remove padding while (i >= 0 && output[i] == 0) { --i; } return new String(Arrays.copyOf(output, i + 1), "UTF-8"); } }