I have written a code in beanshell for encryption and decryption in Jmeter but somehow its not working. I am getting error : In file: inline evaluation of: ``import java.security.InvalidAlgorithmParameterException; import java.security.In . . . '' Encountered "}" at line 19, column 82.
I have added the crypto jar in test plan but issue persists.
Attached is the code.
Working :
I am generating a random string(R1) and encryption it with a public key using RSA algo.
Using the key R1, I need to encrypt the request body using AES algo, CBC mode, PKCS7Padding.
package com.sample.feedbackrating;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.UUID;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Crypto {
public static IvParameterSpec generateIv() {
byte[] iv = new byte[16];
return new IvParameterSpec(iv);
}
public static String encrypt(String algorithm, String input, String secretKey, IvParameterSpec iv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException
{
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, new
SecretKeySpec(secretKey.getBytes(), "AES"), iv);
byte[] cipherText = cipher.doFinal(input.getBytes());
return Base64.getEncoder().encodeToString(cipherText);
}
public static String decrypt(String algorithm, String cipherText, String secretKey, IvParameterSpec iv) throws NoSuchPaddingException, NoSuchAlgorithmException,InvalidAlgorithmParameterException, InvalidKeyException,BadPaddingException, IllegalBlockSizeException
{
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secretKey.getBytes(), "AES"), iv);
byte[] plainText = cipher.doFinal(Base64.getDecoder().decode(cipherText));
return new String(plainText);
}
public static String generateSecretKey() {
return UUID.randomUUID().toString().replace("-", "");
}
}
Encountered "}" is a syntax error so double check your Beanshell script for eventual missing semicolons or closing brackets or whatever. You can use online lint tool like this one to see where exactly the problem is
In general I cannot reproduce your issue:
So it's either a copy-paste issue or a Beanshell-related problem, be aware that starting from JMeter 3.1 you're supposed to use JSR223 Test Elements and Groovy language for scripting, especially for "heavy" tasks like cryptographic operations.
Related
I am trying to encrypt a string in ruby using Cipher with AES algorithm. I have example written in Java. I have taken help from this example and written code in Java but not able to get the same output as in JAVA.
Following is the code written in java
import java.util.Base64;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Key;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import java.util.Arrays;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class HelloWorld {
public static final String PHONENUMBER_PARAM = "phoneNumber";
public static final String PIN_PARAM ="pin";
public static final String MERCHANTID_PARAM = "merchantId";
public static void main(String args[]) throws Exception {
String phoneNumber ="+917738995286";
String pin ="5577";
String merchantId ="527425858";
String encodedKey ="vPDkdTDrcygLPROzd1829A==";
String payLoad = PHONENUMBER_PARAM + "=" + URLEncoder.encode(phoneNumber, "UTF-8")+ "&" + PIN_PARAM + "=" + URLEncoder.encode(pin, "UTF-8") ;
byte[] decodedKey = Base64.getDecoder().decode(encodedKey.getBytes());
Key encryptionKey = new SecretKeySpec(decodedKey, "AES");
byte[] utf8Bytes = payLoad.getBytes("utf-8");
byte[] encryptedBody = encrypt(encryptionKey, utf8Bytes);
String encryptedData = new String(Base64.getEncoder().encode(encryptedBody));
System.out.println("encryptedData:" + encryptedData);
}
private static byte[] encrypt(Key encryptionKey, byte[] data) throws Exception {
Cipher c = Cipher.getInstance("AES");
c.init(1, encryptionKey);
return c.doFinal(data);
}
}
Output of this code is
encryptedData:lE40HlECbxU/mWRivF/+Szm3PprMoLW+Y7x911GczunakbG8l+A2JVEEP8gTw6xy
I tried to write the same code in ruby. Ruby Code is:
payLoad = "phoneNumber=%2B917738995286&pin=5577"
encodedKey = "vPDkdTDrcygLPROzd1829A=="
decodedKey = Base64.decode64(encodedKey)
dKey = decodedKey.each_byte.map { |b| b.to_s(16) }.join
cipher = OpenSSL::Cipher.new('aes128').encrypt
encryptionKey = cipher.update(dKey)
encryptionKey<< cipher.final
utf8Bytes = payLoad.bytes
uKey = utf8Bytes.map { |b| b.to_s(16) }.join
scipher = OpenSSL::Cipher.new('aes128').encrypt
scipher.key = encryptionKey
encryptedBody = scipher.update(uKey)
encryptedBody<< scipher.final
encryptedData = Base64.encode64(encryptedBody)
Output of this code is
CqFmCKJ004PsoXi2tDCTBmx7/iTHVyDsFH9y8NWNrEP3k3bOQp7h8uyl/a7Z\nYi9ZmcXSspo6FCyCo6fJIwPohg==\n
Don't know where is the error. I have already worked for 2 days but not able to get any answer. Any help will be great. Thanks in advance.
The following version outputs the same result as your Java code:
# crypt.rb
require 'base64'
require 'openssl'
payLoad = "phoneNumber=%2B917738995286&pin=5577"
encodedKey = "vPDkdTDrcygLPROzd1829A=="
decodedKey = Base64.decode64(encodedKey)
scipher = OpenSSL::Cipher.new('aes-128-ecb').encrypt
scipher.key = decodedKey
encryptedBody = scipher.update(payLoad)
encryptedBody << scipher.final
encryptedData = Base64.encode64(encryptedBody)
puts encryptedData
$ ruby crypt.rb
# => lE40HlECbxU/mWRivF/+Szm3PprMoLW+Y7x911GczunakbG8l+A2JVEEP8gT
# w6xy
Notable differences from your ruby script version:
You must specify the cipher mode. The problem is that Java defaults to the ECB mode whereas ruby defaults to the CBC mode. By the way, the ECB mode is considered less-secure today and you actually should not use it.
In ruby, you tried to re-encrypt the Base64-decoded version of your encryption key, which is something you don't do in the Java version.
In ruby, there is no need to do the string to byte conversions, you can encrypt strings right away.
So, although the two scripts output the same encrypted data now, I would strongly consider changing the AES mode of operation, to actually stay secure.
I'm trying to create a KeyAgreement with bouncyCastle. It needs EC because I'm working with javacards.
Unfortunately it gives an error when I use Security.addProvider(new BouncyCastleProvider());:
Multiple markers at this line
- Syntax error, insert ")" to complete MethodDeclaration
- Syntax error, insert "SimpleName" to complete
QualifiedName
- Syntax error, insert "Identifier (" to complete
MethodHeaderName
- Syntax error on token ".", # expected after this token
If I leave that line out, it gives an error:
Exception in thread "main" java.security.NoSuchProviderException: no such provider: BC
at sun.security.jca.GetInstance.getService(Unknown Source)
at javax.crypto.JceSecurity.getInstance(JceSecurity.java:97)
at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:230)
at pract_LCP.keyAgreement.<init>(keyAgreement.java:30)
at pract_LCP.main.main(main.java:12)
So I have to force bouncyCastle I guess.
my code:
package pract_LCP;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import org.bouncycastle.*;
import javax.crypto.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class keyAgreement {
Security.addProvider(new BouncyCastleProvider());
//Security.addProvider(new BouncyCastleProvider());
private String StringPrivatekey="23dc5cf316583c2e60e36c405b10d03541f4a76f6da2852d";
private String StringPublicKey="47595243a6737a00fe5d911c1a3305be5c108bf4f68b01945c40358143f28077fad4a8a51f190b6d8bb8b580c88011335";
private PrivateKey convertPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException{
byte[] privateKeyBytes=privateKey.getBytes();
KeyFactory kf = KeyFactory.getInstance("EC"); // or "EC" or whatever
PrivateKey converted = kf.generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
return converted;
}
private PublicKey convertPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException{
byte[] publicKeyBytes=publicKey.getBytes();
KeyFactory kf = KeyFactory.getInstance("EC"); // or "EC" or whatever
PublicKey converted = kf.generatePublic(new PKCS8EncodedKeySpec(publicKeyBytes));
return converted;
}
public keyAgreement() throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException{
KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDH", "BC");
aKeyAgree.init(convertPrivateKey(StringPrivatekey));
aKeyAgree.doPhase(convertPublicKey(StringPublicKey), true);
byte[] aSecret = aKeyAgree.generateSecret();
String str = new String(aSecret, StandardCharsets.UTF_8);
System.out.println("keyagr"+str);
}
}
I am totally new to security and signature verification and so far I couldn't find a place which explained the basics of signature verification. I need to verify the signature of a file by obtaining the public key from the appropriate certificate available from certificate store. the tutorial in Java (https://docs.oracle.com/javase/tutorial/security/apisign/versig.html) doesn't teach how to obtain a certificate from the trusted certificate store and verify using that. I went through Bouncy castle WIKI http://www.bouncycastle.org/wiki/display/JA1/BC+Version+2+APIs but its not really explanatory for a beginner. How do I do this? Given a signed file, how can I check for its public key from the certificate store and verify if its the right person who has sent the file? Please advice.
Because you did not provide what build management you use, I assume it will be Maven.
First, include BouncyCastle in your dependency
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.53</version>
</dependency>
After that, you need to make a util class that you will be using for sign or verify the certificate. Something like this:
package your.pack.location;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* Author: harunalfat
*/
public class SignatureUtils {
private static final Logger log = LogManager.getLogger(SignatureUtils.class);
public static String sign(String plainText, PrivateKey privateKey) throws Exception {
byte[] data = plainText.getBytes("ISO-8859-1");
Signature signature = Signature.getInstance("SHA1WithRSA", "BC");
signature.initSign(privateKey);
signature.update(data);
return Base64.toBase64String(signature.sign());
}
public static boolean verify(String plainText, String signString, PublicKey publicKey) throws Exception{
byte[] data = plainText.getBytes("ISO-8859-1");
Signature signature = Signature.getInstance("SHA1WithRSA", "BC");
signature.initVerify(publicKey);
signature.update(data);
byte[] signByte = Base64.decode(signString);
return signature.verify(signByte);
}
private static PemObject getPemObjectFromResource(String fileLocation) throws IOException {
Resource resource = new ClassPathResource(fileLocation);
InputStream is = resource.getInputStream();
PemObject pemObject = new PemReader(new InputStreamReader( is )).readPemObject();
return pemObject;
}
private static X509EncodedKeySpec getPubKeySpec(String fileLocation) throws IOException, NoSuchAlgorithmException {
PemObject pemObject = getPemObjectFromResource(fileLocation);
byte[] data = pemObject.getContent();
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(data);
return keySpec;
}
private static PKCS8EncodedKeySpec getPriKeySpec(String fileLocation) throws IOException, NoSuchAlgorithmException {
PemObject pemObject = getPemObjectFromResource(fileLocation);
byte[] data = pemObject.getContent();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data);
return keySpec;
}
public static PublicKey getPublicKey(String fileLocation) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
KeyFactory kf = KeyFactory.getInstance("RSA");
KeySpec keySpec = getPubKeySpec(fileLocation);
return kf.generatePublic(keySpec);
}
public static PrivateKey getPrivateKey(String fileLocation) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
KeyFactory kf = KeyFactory.getInstance("RSA");
KeySpec keySpec = getPriKeySpec(fileLocation);
return kf.generatePrivate(keySpec);
}
}
And then you will use it like this
package your.another.pack;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tomcat.util.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Test;
import org.mockito.MockitoAnnotations;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import static org.junit.Assert.assertTrue;
/**
* Author: harunalfat
*/
public class SignatureUtilsTest {
private static final Logger log = LogManager.getLogger(SignatureUtilsTest.class);
private static final String PLAIN = "attack at dawn";
#Test
public void testSignAndVerify() throws Exception {
Security.addProvider(new BouncyCastleProvider()); // <-- IMPORTANT!!! This will add BouncyCastle as provider in Java Security
PrivateKey privateKey = SignatureUtils.getPrivateKey("key/private2.pem"); // This is located on src/main/resources/key/private2.pem
PublicKey publicKey = SignatureUtils.getPublicKey("key/public2.pem"); // This is located on src/main/resources/key/public2.pem
// In this example, I use junit test, so it will be on src/test/resources/...
log.info("Private Key : "+Base64.encodeBase64String(privateKey.getEncoded()));
log.info("Public Key : "+Base64.encodeBase64String(publicKey.getEncoded()));
String sign = SignatureUtils.sign(PLAIN, privateKey);
log.info("Plain String : "+PLAIN);
log.info("Sign : "+sign);
boolean result = SignatureUtils.verify(PLAIN,sign, publicKey);
log.info("Result : "+result);
assertTrue(result);
}
}
Of course, you can change the Signature instance with another Algorithm. In my case I use "SHA1WithRSA", but you get the point right?
With this, someone will encrypt their data using their private key, and send it to you. After that, you will verify the data using the public key they give.
In example, Bob send to you message about money amount he sent to you ($5000), and sign it using their private key, become encrypted. When the data arrived to you, you know Bob supposed to send $5000, then you verify the encrypted data with text $5000 and public key Bob share, but is it really $5000 OR does it comes from Bob?
If the data has been changed, OR when someday you ask for some Money to Bob, but the message tapped by someone else and s/he send you the amount message with private key other than Bob's, you will know.
Feel free to ask :)
I try to send with ObjectOutpuStream this RSA custom Object that I have done Serializable. Why ObjectInputStream receives a null pointer and throw exception NullPointer because No class founded
import java.io.Serializable;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAKeyGenParameterSpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
public class NewRSA implements Serializable{
private KeyPair keys ;
public NewRSA(){
this.keys=null;
}
public NewRSA(KeyPair keys)
{
this.keys=keys;
}
public KeyPair getKPair()
{
return keys;
}
public void setKPair(KeyPair keys)
{
this.keys=keys;
}
public KeyPair generateRsaKeyPair(int keySize, BigInteger publicExponent)
{
try
{
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(keySize, publicExponent);
keyGen.initialize(spec);
keys = keyGen.generateKeyPair();
}
catch(Exception e)
{
}
return keys;
}
public byte[] rsaEncrypt(byte[] original, PublicKey key) throws InvalidKeyException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException, BadPaddingException
{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(original);
}
public static byte[] rsaDecrypt(byte[] encrypted, PrivateKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(encrypted);
}
}
Error is:
No classe
Output PrintStackTrace
java.lang.ClassNotFoundException: com.android.org.conscrypt.OpenSSLRSAPrivateCrtKey
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:626)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1613)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at stefano.Server$ServerThread.attemptLog(Server.java:268)
at stefano.Server$ServerThread.handshake(Server.java:402)
at stefano.Server$ServerThread.run(Server.java:428)
Serializable classes can't really be converted from the Android JVM to the usual Oracle/OpenJDK JVM, you can use the Externalizable interface to manually serialize your class and retrieve it on the backend. There is however a solution that might work, it's to write your backend API in an IDE (using the Oracle Java) and compile it. It might work because the class signatures and headers are the same (it's a 50/50 Chance).
I have a symmetric Key in my JKS (Java Key Store) file, I want to wrap my private key with a symmetric key.
Again I am using wrappedBytes to PrivateKey Object. And finally I want the KeyPair Object.
The below code gives the following error message:
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=125, too big.**
public KeyPair wrapPrivateKeyWithSymmetricKey(KeyPair keyPair) {
try {
PrivateKey priv = keyPair.getPrivate();
SecretKey symmetricKey = "bjksabfkasdbgvkasbvkkj";//symmetricKey from jks file
//wrapping Private Key
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.WRAP_MODE, symmetricKey);
byte[] wrappedKey = cipher.wrap(priv);
//wrappedKey bytes to PrivateKey Object
KeyFactory keyFactory = KeyFactory.getInstance(priv.getAlgorithm());
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(wrappedKey);
PrivateKey privateKey2 = keyFactory.generatePrivate(privateKeySpec); //above Error Throwing in this line
return new KeyPair(keyPair.getPublic(), privateKey2);;
}
How can I solve this?
In your example, wrappedBytes isn't in a PKCS #8 format. It's simply some AES encrypted blocks—essentially random data—with no encoded structure.
If you want to create an encrypted PKCS #8 (formally, EncryptedPrivateKeyInfo) you'll need a library that handles that. The built-in API you are trying to use only handles its clear-text payload, PrivateKeyInfo (as described in its documentation).
There isn't much to the wrapper, and you could write the necessary DER coding yourself, or use a library like BouncyCastle.
Here's code, using BouncyCastle to encoded and decode the EncryptyedPrivateKeyInfo structure. The useless class provided by the JCE doesn't work, because of poor handling of the key encryption algorithm identifier and its parameters.
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
final class PKCS8
{
private static final ASN1ObjectIdentifier AES = ASN1ObjectIdentifier.getInstance(NISTObjectIdentifiers.id_aes128_CBC);
static RSAPublicKey toPublic(RSAPrivateCrtKey pvt)
throws GeneralSecurityException
{
RSAPublicKeySpec pub = new RSAPublicKeySpec(pvt.getModulus(), pvt.getPublicExponent());
KeyFactory f = KeyFactory.getInstance("RSA");
return (RSAPublicKey) f.generatePublic(pub);
}
static byte[] encrypt(SecretKey secret, PrivateKey pvt)
throws Exception
{
Cipher enc = Cipher.getInstance("AES/CBC/PKCS5Padding");
enc.init(Cipher.WRAP_MODE, secret);
ASN1Encodable params = new DEROctetString(enc.getIV());
AlgorithmIdentifier algId = new AlgorithmIdentifier(AES, params);
byte[] ciphertext = enc.wrap(pvt);
return new EncryptedPrivateKeyInfo(algId, ciphertext).getEncoded();
}
static PrivateKey decrypt(SecretKey secret, byte[] pkcs8)
throws Exception
{
EncryptedPrivateKeyInfo info = new PKCS8EncryptedPrivateKeyInfo(pkcs8).toASN1Structure();
AlgorithmIdentifier id = info.getEncryptionAlgorithm();
byte[] iv = ((ASN1OctetString) id.getParameters()).getOctets();
Cipher dec = Cipher.getInstance("AES/CBC/PKCS5Padding");
dec.init(Cipher.UNWRAP_MODE, secret, new IvParameterSpec(iv));
return (PrivateKey) dec.unwrap(info.getEncryptedData(), "RSA", Cipher.PRIVATE_KEY);
}
}