BeanShell Sampler error: Typed variable declaration: Method Invocation KeyFactory.getInstance

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

BeanShell Sampler error: Typed variable declaration: Method Invocation KeyFactory.getInstance

Markus Obermann
Hey all,
im using JMeter 5.0 with JRE 9.0.2.
I have a ECDSA Private Key on my disk and want to sign some file on my disk too.My priv. key looks like this:
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDzESrZFmTaOozu2NyiS8LMZGqkHfpSOoI/qA9Lw+d4NoAcGBSuBBAAK
oUQDQgAE7kIqoSQzC/UUXdFdQ9Xvu1Lri7pFfd7xDbQWhSqHaDtj+XY36Z1Cznun
GDxlA0AavdVDuoGXxNQPIed3FxPE3Q==
-----END EC PRIVATE KEY-----
note:this is of course not a real key. its just what my file looks like if i view it with vi.

I found this lil code snippet.
File privkeyfile = new File(path_to_privkey_file);File datafile = new File(path_to_datafile);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) privkeyfile.length()];
dis.readFully(keyBytes);
dis.close();
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("ECDSA");PrivateKey privateKey = factory.generatePrivate(spec);
Well the next step would be to sign my file with my private key and then encode it base64.
I though of doing it like this:

Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
ecdsaSign.initSign(privateKey);
ecdsaSign.update(plaintext.getBytes("UTF-8"));
byte[] signature = ecdsaSign.sign();
String pub = Base64.getEncoder().encodeToString(publicKey.getEncoded());
String sig = Base64.getEncoder().encodeToString(signature);

But in BeanShell i will get the Error: "Typed variable declaration: Method Invocation KeyFactory.getInstance"
Any ideas?

P.S.
ofc i do have imported the java.security.KeyFactory; and PKCS8EncodedKeySpec.



Reply | Threaded
Open this post in threaded view
|

Re: BeanShell Sampler error: Typed variable declaration: Method Invocation KeyFactory.getInstance

Felix Schumacher

Am 13.09.19 um 13:27 schrieb Markus Obermann:

> Hey all,
> im using JMeter 5.0 with JRE 9.0.2.
> I have a ECDSA Private Key on my disk and want to sign some file on my disk too.My priv. key looks like this:
> -----BEGIN EC PARAMETERS-----
> BgUrgQQACg==
> -----END EC PARAMETERS-----
> -----BEGIN EC PRIVATE KEY-----
> MHQCAQEEIDzESrZFmTaOozu2NyiS8LMZGqkHfpSOoI/qA9Lw+d4NoAcGBSuBBAAK
> oUQDQgAE7kIqoSQzC/UUXdFdQ9Xvu1Lri7pFfd7xDbQWhSqHaDtj+XY36Z1Cznun
> GDxlA0AavdVDuoGXxNQPIed3FxPE3Q==
> -----END EC PRIVATE KEY-----
> note:this is of course not a real key. its just what my file looks like if i view it with vi.
>
> I found this lil code snippet.
> File privkeyfile = new File(path_to_privkey_file);File datafile = new File(path_to_datafile);
> FileInputStream fis = new FileInputStream(f);
> DataInputStream dis = new DataInputStream(fis);
> byte[] keyBytes = new byte[(int) privkeyfile.length()];
> dis.readFully(keyBytes);
> dis.close();
> PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
> KeyFactory kf = KeyFactory.getInstance("ECDSA");PrivateKey privateKey = factory.generatePrivate(spec);
> Well the next step would be to sign my file with my private key and then encode it base64.
> I though of doing it like this:
>
> Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
> ecdsaSign.initSign(privateKey);
> ecdsaSign.update(plaintext.getBytes("UTF-8"));
> byte[] signature = ecdsaSign.sign();
> String pub = Base64.getEncoder().encodeToString(publicKey.getEncoded());
> String sig = Base64.getEncoder().encodeToString(signature);
>
> But in BeanShell i will get the Error: "Typed variable declaration: Method Invocation KeyFactory.getInstance"
> Any ideas?

I would try and use a JSR 223 Sampler with groovy instead of BeanShell.
BeanShell is getting old and has problems with newer Java features.
Groovy has nice syntactic sugar and is fast enough for most settings.

Regards

 Felix

>
> P.S.
> ofc i do have imported the java.security.KeyFactory; and PKCS8EncodedKeySpec.
>
>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: BeanShell Sampler error: Typed variable declaration: Method Invocation KeyFactory.getInstance

Felix Schumacher

Am 13.09.19 um 14:07 schrieb Felix Schumacher:

> Am 13.09.19 um 13:27 schrieb Markus Obermann:
>> Hey all,
>> im using JMeter 5.0 with JRE 9.0.2.
>> I have a ECDSA Private Key on my disk and want to sign some file on my disk too.My priv. key looks like this:
>> -----BEGIN EC PARAMETERS-----
>> BgUrgQQACg==
>> -----END EC PARAMETERS-----
>> -----BEGIN EC PRIVATE KEY-----
>> MHQCAQEEIDzESrZFmTaOozu2NyiS8LMZGqkHfpSOoI/qA9Lw+d4NoAcGBSuBBAAK
>> oUQDQgAE7kIqoSQzC/UUXdFdQ9Xvu1Lri7pFfd7xDbQWhSqHaDtj+XY36Z1Cznun
>> GDxlA0AavdVDuoGXxNQPIed3FxPE3Q==
>> -----END EC PRIVATE KEY-----
>> note:this is of course not a real key. its just what my file looks like if i view it with vi.
>>
>> I found this lil code snippet.
>> File privkeyfile = new File(path_to_privkey_file);File datafile = new File(path_to_datafile);
>> FileInputStream fis = new FileInputStream(f);
>> DataInputStream dis = new DataInputStream(fis);
>> byte[] keyBytes = new byte[(int) privkeyfile.length()];
>> dis.readFully(keyBytes);
>> dis.close();
>> PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
>> KeyFactory kf = KeyFactory.getInstance("ECDSA");PrivateKey privateKey = factory.generatePrivate(spec);
>> Well the next step would be to sign my file with my private key and then encode it base64.
>> I though of doing it like this:
>>
>> Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
>> ecdsaSign.initSign(privateKey);
>> ecdsaSign.update(plaintext.getBytes("UTF-8"));
>> byte[] signature = ecdsaSign.sign();
>> String pub = Base64.getEncoder().encodeToString(publicKey.getEncoded());
>> String sig = Base64.getEncoder().encodeToString(signature);
>>
>> But in BeanShell i will get the Error: "Typed variable declaration: Method Invocation KeyFactory.getInstance"
>> Any ideas?
> I would try and use a JSR 223 Sampler with groovy instead of BeanShell.
> BeanShell is getting old and has problems with newer Java features.
> Groovy has nice syntactic sugar and is fast enough for most settings.

I have tried to convert the above snippet into groovy code:

import java.security.KeyFactory
import java.security.Signature
import java.security.PrivateKey
import java.security.spec.PKCS8EncodedKeySpec

String path_to_privkey_file="/tmp/key.pem"

File privkeyfile = new File(path_to_privkey_file)

byte[] keyBytes = new byte[(int) privkeyfile.length()]

FileInputStream fis = new FileInputStream(privkeyfile)
DataInputStream dis = new DataInputStream(fis)
try {
    dis.readFully(keyBytes)
} finally {
    dis.close()
    fis.close()
}

PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes)
log.info("Format: {}", spec.format)
KeyFactory factory = KeyFactory.getInstance("EC")
PrivateKey privateKey = factory.generatePrivate(spec)

Signature ecdsaSign = Signature.getInstance("SHA256withECDSA")
ecdsaSign.initSign(privateKey)
ecdsaSign.update("Hello, World!".getBytes("UTF-8"))

byte[] signature = ecdsaSign.sign()

String sig = Base64.getEncoder().encodeToString(signature)

log.info(" signature: {}", sig)
return sig

The key.pem file has to be in DER format to be valid.

I generated my test key with

$ openssl req -x509 -nodes -days 3650 -newkey ec:<(openssl ecparam -name
prime256v1) -keyout ecdsakey.pem -out ecdsacert.pem
$ openssl pkcs8 -in ecdsakey.pem -out /tmp/key.pem -topk8 -nocrypt
-outform DER

Java 8 seems to use EC for the ECDSA cipher, therefore I  changed the
string "ECDSA" to "EC".

That seemed to work for me

 Felix

>
> Regards
>
>  Felix
>
>> P.S.
>> ofc i do have imported the java.security.KeyFactory; and PKCS8EncodedKeySpec.
>>
>>
>>
>>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: BeanShell Sampler error: Typed variable declaration: Method Invocation KeyFactory.getInstance

Markus Obermann

   Am Freitag, 13. September 2019, 15:16:50 MESZ hat Felix Schumacher <[hidden email]> Folgendes geschrieben:  
 
Am 13.09.19 um 14:07 schrieb Felix Schumacher:

> Am 13.09.19 um 13:27 schrieb Markus Obermann:
>> Hey all,
>> im using JMeter 5.0 with JRE 9.0.2.
>> I have a ECDSA Private Key on my disk and want to sign some file on my disk too.My priv. key looks like this:
>> -----BEGIN EC PARAMETERS-----
>> BgUrgQQACg==
>> -----END EC PARAMETERS-----
>> -----BEGIN EC PRIVATE KEY-----
>> MHQCAQEEIDzESrZFmTaOozu2NyiS8LMZGqkHfpSOoI/qA9Lw+d4NoAcGBSuBBAAK
>> oUQDQgAE7kIqoSQzC/UUXdFdQ9Xvu1Lri7pFfd7xDbQWhSqHaDtj+XY36Z1Cznun
>> GDxlA0AavdVDuoGXxNQPIed3FxPE3Q==
>> -----END EC PRIVATE KEY-----
>> note:this is of course not a real key. its just what my file looks like if i view it with vi.
>>
>> I found this lil code snippet.
>> File privkeyfile = new File(path_to_privkey_file);File datafile = new File(path_to_datafile);
>> FileInputStream fis = new FileInputStream(f);
>> DataInputStream dis = new DataInputStream(fis);
>> byte[] keyBytes = new byte[(int) privkeyfile.length()];
>> dis.readFully(keyBytes);
>> dis.close();
>> PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
>> KeyFactory kf = KeyFactory.getInstance("ECDSA");PrivateKey privateKey = factory.generatePrivate(spec);
>> Well the next step would be to sign my file with my private key and then encode it base64.
>> I though of doing it like this:
>>
>> Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
>> ecdsaSign.initSign(privateKey);
>> ecdsaSign.update(plaintext.getBytes("UTF-8"));
>> byte[] signature = ecdsaSign.sign();
>> String pub = Base64.getEncoder().encodeToString(publicKey.getEncoded());
>> String sig = Base64.getEncoder().encodeToString(signature);
>>
>> But in BeanShell i will get the Error: "Typed variable declaration: Method Invocation KeyFactory.getInstance"
>> Any ideas?
> I would try and use a JSR 223 Sampler with groovy instead of BeanShell.
> BeanShell is getting old and has problems with newer Java features.
> Groovy has nice syntactic sugar and is fast enough for most settings.

I have tried to convert the above snippet into groovy code:

import java.security.KeyFactory
import java.security.Signature
import java.security.PrivateKey
import java.security.spec.PKCS8EncodedKeySpec

String path_to_privkey_file="/tmp/key.pem"

File privkeyfile = new File(path_to_privkey_file)

byte[] keyBytes = new byte[(int) privkeyfile.length()]

FileInputStream fis = new FileInputStream(privkeyfile)
DataInputStream dis = new DataInputStream(fis)
try {
    dis.readFully(keyBytes)
} finally {
    dis.close()
    fis.close()
}

PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes)
log.info("Format: {}", spec.format)
KeyFactory factory = KeyFactory.getInstance("EC")
PrivateKey privateKey = factory.generatePrivate(spec)

Signature ecdsaSign = Signature.getInstance("SHA256withECDSA")
ecdsaSign.initSign(privateKey)
ecdsaSign.update("Hello, World!".getBytes("UTF-8"))

byte[] signature = ecdsaSign.sign()

String sig = Base64.getEncoder().encodeToString(signature)

log.info(" signature: {}", sig)
return sig

The key.pem file has to be in DER format to be valid.

I generated my test key with

$ openssl req -x509 -nodes -days 3650 -newkey ec:<(openssl ecparam -name
prime256v1) -keyout ecdsakey.pem -out ecdsacert.pem
$ openssl pkcs8 -in ecdsakey.pem -out /tmp/key.pem -topk8 -nocrypt
-outform DER

Java 8 seems to use EC for the ECDSA cipher, therefore I  changed the
string "ECDSA" to "EC".

That seemed to work for me

 Felix

>
> Regards
>
>  Felix
>
>> P.S.
>> ofc i do have imported the java.security.KeyFactory; and PKCS8EncodedKeySpec.
>>
>>
Hi All, hi Felix,
thanks for your quick reply.
First i also used JSR223 Sampler and first is spotted was that's its better than beanshell.
Yes i also found out that i have to use "EC" insted of "ECDSA" thats why i got the exception with beanshell which was not helpfull.Then i had to convert my privkey into der using the same command as u (openssl pkcs8...)
The next steps were easy :)
Btw. im using "byte[] keyBytes = FileUtils.readFilteToByteArray(file)" to get the File into my byte array. This works perfect.You have to import org.apache.commons.io.FileUtils
So having my privatekey in the correct format loaded i just get my file from disk - and sign it.Thus i do:while((len = bufin.read(buffer)) >=0){ecdsaSign.update(buffer, 0 , len);};bufin.close();byte[] sign = ecdsaSign.sign();

It's working :)
Thank you again for the quick help.




>>
>>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

 
Reply | Threaded
Open this post in threaded view
|

Re: BeanShell Sampler error: Typed variable declaration: Method Invocation KeyFactory.getInstance

Felix Schumacher

Am 13.09.19 um 15:47 schrieb Markus Obermann:

>    Am Freitag, 13. September 2019, 15:16:50 MESZ hat Felix Schumacher <[hidden email]> Folgendes geschrieben:  
>  
> Am 13.09.19 um 14:07 schrieb Felix Schumacher:
>> Am 13.09.19 um 13:27 schrieb Markus Obermann:
>>> Hey all,
>>> im using JMeter 5.0 with JRE 9.0.2.
>>> I have a ECDSA Private Key on my disk and want to sign some file on my disk too.My priv. key looks like this:
>>> -----BEGIN EC PARAMETERS-----
>>> BgUrgQQACg==
>>> -----END EC PARAMETERS-----
>>> -----BEGIN EC PRIVATE KEY-----
>>> MHQCAQEEIDzESrZFmTaOozu2NyiS8LMZGqkHfpSOoI/qA9Lw+d4NoAcGBSuBBAAK
>>> oUQDQgAE7kIqoSQzC/UUXdFdQ9Xvu1Lri7pFfd7xDbQWhSqHaDtj+XY36Z1Cznun
>>> GDxlA0AavdVDuoGXxNQPIed3FxPE3Q==
>>> -----END EC PRIVATE KEY-----
>>> note:this is of course not a real key. its just what my file looks like if i view it with vi.
>>>
>>> I found this lil code snippet.
>>> File privkeyfile = new File(path_to_privkey_file);File datafile = new File(path_to_datafile);
>>> FileInputStream fis = new FileInputStream(f);
>>> DataInputStream dis = new DataInputStream(fis);
>>> byte[] keyBytes = new byte[(int) privkeyfile.length()];
>>> dis.readFully(keyBytes);
>>> dis.close();
>>> PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
>>> KeyFactory kf = KeyFactory.getInstance("ECDSA");PrivateKey privateKey = factory.generatePrivate(spec);
>>> Well the next step would be to sign my file with my private key and then encode it base64.
>>> I though of doing it like this:
>>>
>>> Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
>>> ecdsaSign.initSign(privateKey);
>>> ecdsaSign.update(plaintext.getBytes("UTF-8"));
>>> byte[] signature = ecdsaSign.sign();
>>> String pub = Base64.getEncoder().encodeToString(publicKey.getEncoded());
>>> String sig = Base64.getEncoder().encodeToString(signature);
>>>
>>> But in BeanShell i will get the Error: "Typed variable declaration: Method Invocation KeyFactory.getInstance"
>>> Any ideas?
>> I would try and use a JSR 223 Sampler with groovy instead of BeanShell.
>> BeanShell is getting old and has problems with newer Java features.
>> Groovy has nice syntactic sugar and is fast enough for most settings.
> I have tried to convert the above snippet into groovy code:
>
> import java.security.KeyFactory
> import java.security.Signature
> import java.security.PrivateKey
> import java.security.spec.PKCS8EncodedKeySpec
>
> String path_to_privkey_file="/tmp/key.pem"
>
> File privkeyfile = new File(path_to_privkey_file)
>
> byte[] keyBytes = new byte[(int) privkeyfile.length()]
>
> FileInputStream fis = new FileInputStream(privkeyfile)
> DataInputStream dis = new DataInputStream(fis)
> try {
>     dis.readFully(keyBytes)
> } finally {
>     dis.close()
>     fis.close()
> }
>
> PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes)
> log.info("Format: {}", spec.format)
> KeyFactory factory = KeyFactory.getInstance("EC")
> PrivateKey privateKey = factory.generatePrivate(spec)
>
> Signature ecdsaSign = Signature.getInstance("SHA256withECDSA")
> ecdsaSign.initSign(privateKey)
> ecdsaSign.update("Hello, World!".getBytes("UTF-8"))
>
> byte[] signature = ecdsaSign.sign()
>
> String sig = Base64.getEncoder().encodeToString(signature)
>
> log.info(" signature: {}", sig)
> return sig
>
> The key.pem file has to be in DER format to be valid.
>
> I generated my test key with
>
> $ openssl req -x509 -nodes -days 3650 -newkey ec:<(openssl ecparam -name
> prime256v1) -keyout ecdsakey.pem -out ecdsacert.pem
> $ openssl pkcs8 -in ecdsakey.pem -out /tmp/key.pem -topk8 -nocrypt
> -outform DER
>
> Java 8 seems to use EC for the ECDSA cipher, therefore I  changed the
> string "ECDSA" to "EC".
>
> That seemed to work for me
>
>  Felix
>
>> Regards
>>
>>  Felix
>>
>>> P.S.
>>> ofc i do have imported the java.security.KeyFactory; and PKCS8EncodedKeySpec.
>>>
>>>
> Hi All, hi Felix,
> thanks for your quick reply.
> First i also used JSR223 Sampler and first is spotted was that's its better than beanshell.
> Yes i also found out that i have to use "EC" insted of "ECDSA" thats why i got the exception with beanshell which was not helpfull.Then i had to convert my privkey into der using the same command as u (openssl pkcs8...)
> The next steps were easy :)
> Btw. im using "byte[] keyBytes = FileUtils.readFilteToByteArray(file)" to get the File into my byte array. This works perfect.You have to import org.apache.commons.io.FileUtils
> So having my privatekey in the correct format loaded i just get my file from disk - and sign it.Thus i do:while((len = bufin.read(buffer)) >=0){ecdsaSign.update(buffer, 0 , len);};bufin.close();byte[] sign = ecdsaSign.sign();
>
> It's working :)
> Thank you again for the quick help.

If you want, you can now try to use more groovy methods that enhance the
File, bytes and other java objects.

For example File#getBytes() gives you the content of the file as byte[].
Together with some groovy syntactic sugar, such as that setter/getters
are recognized automatically, you can shorten this to

def privKey = new File(pathToPrivKey).bytes

Reading bytes from a File (even buffered) and consuming it can be
achieved with the File#eachByte(length, Closure) method, which results in

new File(pathToData).eachBytes(4096, { buffer, length ->
ecdsaSign.update(buffer, 0 , length) })

And byte even has a Base64 encode method builtin

def sig = ecdsaSign.sign().encodeBase64()

That could shorten your code a bit and make it hopefully more readable.

Felix

>
>
>
>
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>  

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]