Error while compiling Java files into DLL assemblies - java

I have been trying to convert a Java class into DLL using IKVM.
IKVM converts that easily without errors. But while running it in VS, it throws the following exceptions:
System.TypeInitializationException: 'The type initializer for 'sun.security.jca.Providers' threw an exception.
**1 of 2 Inner Exceptions** : TypeInitializationException: The type initializer for 'java.security.Security' threw an exception.
**2 of 2 Inner Exceptions** : - InnerException {"Method not found: 'Void System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.Security.AccessControl.FileSystemRights, System.IO.FileShare, Int32, System.IO.FileOptions)'."} System.Exception {System.MissingMethodException}.
I can't understand the reason of these Exceptions.
My Java Code is :
package aesgzip;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.Scanner;
public class AESGzip {
private static final String key = MyKeyString;
private static final String IV = MyIV;
public static byte[] decrypt(byte[] encrypted) {
try {
IvParameterSpec IVSpec = new IvParameterSpec(IV.getBytes("UTF-8"));
SecretKeySpec KEYSpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(2, KEYSpec, IVSpec);
return cipher.doFinal(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
My C# Code is :
using System;
using aesgzip;
namespace AESTest
{
public partial class Form1 : Form
{
public Form1()
{
byte[] b = Convert.FromBase64String(myBASE64String);
byte[] x = AESGzip.decrypt(b);
Console.WriteLine(x);
}
}
}

Related

Problem with encryption/Decryption code written in Jmeter

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.

DER Decode ECDSA Signature in Java

I have generated an ECDSA signature in Java and I would like to get the R and S values from it. It is my understanding that the signature I have generated is DER encoded. Can someone please provide me with some Java code (maybe using Bouncy Castle) to retrieve the R and S values as BigIntegers?
Note: In case it helps, I generated the signature using a built in provider via the JCE's Signature class and the signature lengths for my P_256 EC key pair hover between 70 and 72 bytes usually.
I was able to solve this myself. In case it helps anyone here is how I did it (most exception handling has been stripped for readability):
import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.Signature;
import java.security.spec.ECGenParameterSpec;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class DecodeEcdsaSignature {
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
byte[] signature = getSignature();
ASN1Primitive asn1 = toAsn1Primitive(signature);
if (asn1 instanceof ASN1Sequence) {
ASN1Sequence asn1Sequence = (ASN1Sequence) asn1;
ASN1Encodable[] asn1Encodables = asn1Sequence.toArray();
for (ASN1Encodable asn1Encodable : asn1Encodables) {
ASN1Primitive asn1Primitive = asn1Encodable.toASN1Primitive();
if (asn1Primitive instanceof ASN1Integer) {
ASN1Integer asn1Integer = (ASN1Integer) asn1Primitive;
BigInteger integer = asn1Integer.getValue();
System.out.println(integer.toString());
}
}
}
}
private static ASN1Primitive toAsn1Primitive(byte[] data) throws Exception
{
try (ByteArrayInputStream inStream = new ByteArrayInputStream(data);
ASN1InputStream asnInputStream = new ASN1InputStream(inStream);)
{
return asnInputStream.readObject();
}
}
private static byte[] getSignature() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA");
ECGenParameterSpec ecParameterSpec = new ECGenParameterSpec("P-256");
keyPairGenerator.initialize(ecParameterSpec);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initSign(keyPair.getPrivate());
signature.update("message to sign".getBytes("UTF-8"));
return signature.sign();
}
}

Java, Illegal Access Error when accessing another class

I am trying to write a ssl decryption program. I found some old code from 2010 and have tried to get it to run. After finally being able to compile it I now get this error:
Exception in thread "main" java.lang.IllegalAccessError: tried to access class sun.security.ssl.CipherSuite from class sun.security.ssl.decrypt at sun.security.ssl.decrypt.main(decrypt.java:36)
which is the line where I call CipherSuite.valueOf(0x00, 0x2f); (deleted some comment lines that's why it might be another line number here)
Now I have read that it would probably be a problem with the method valueOf() being private. Since I am a newbie to java I don't know how to handle that, because the code I would need to change is in a jar. (Using openjdk-1.7)
On the other hand, it says here
that the method is just static. Also checking with .isAvailable() like recommended in the link above (at the .valueOf method) does not help.
Any suggestions?
Here is the code I got so far:
package sun.security.ssl;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.SecretKey;
import javax.xml.bind.DatatypeConverter;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.security.internal.spec.TlsKeyMaterialParameterSpec;
import sun.security.internal.spec.TlsKeyMaterialSpec;
import sun.security.ssl.CipherSuite.BulkCipher;
public class decrypt {
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException {
byte[] clrnd = DatatypeConverter.parseHexBinary("be9b706c800f93526913732a356c7e7fe9383ace52f5ed120d38a81db07e903d");
byte[] srvrnd = DatatypeConverter.parseHexBinary("56af786428bc3e0c69ef2fdd9f6e3456ceae660a323d6109e9554b4af7fe6652");
ProtocolVersion pv = ProtocolVersion.valueOf(0x03, 0x03);
CipherSuite cipher_suite = CipherSuite.valueOf(0x00, 0x2f);
String KeyAlgo = cipher_suite.cipher.algorithm;
String Master_Key = "c55ca8dd56fa59b80b8ff01d9a1d4f04251aec41ab6340e8db118b3d4d2ef895cc51592f9bcd5dbde5eda9d5ad386f34";
byte[] master_secret = DatatypeConverter.parseBase64Binary(Master_Key);
byte[] client_app_data = DatatypeConverter.parseHexBinary("715e388b6ed9339faa6fc640f329c358");
SecretKey masterkey = new SecretKeySpec(master_secret, 0, master_secret.length, KeyAlgo);
//Calculate connection keys
BulkCipher cipher = cipher_suite.cipher;
int expandedKeySize = cipher_suite.exportable ? cipher.expandedKeySize : 0;
KeyGenerator kg = JsseJce.getKeyGenerator("SunTlsKeyMaterial");
int pv_major = pv.major;
int pv_minor = pv.minor;
try {
kg.init(new TlsKeyMaterialParameterSpec(masterkey, pv_major, pv_minor, clrnd, srvrnd, cipher.algorithm, cipher.keySize, expandedKeySize, cipher.ivSize, cipher_suite.macAlg.size, cipher_suite.prfAlg.getPRFHashAlg(), cipher_suite. prfAlg.getPRFHashLength(), cipher_suite.prfAlg.getPRFBlockSize()));
} catch (InvalidAlgorithmParameterException ex) {
Logger.getLogger(decrypt.class.getName()).log(Level.SEVERE, null, ex);
}
TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec)kg.generateKey();
SecretKey clntWriteKey = keySpec.getClientCipherKey();
IvParameterSpec clntWriteIV = keySpec.getClientIv();
SecureRandom clientrandom = new SecureRandom(clrnd);
CipherBox svbox = cipher_suite.cipher.newCipher(pv, clntWriteKey, clntWriteIV, clientrandom, false);
try {
svbox.decrypt(client_app_data, 5, client_app_data.length-5, 0);
} catch (BadPaddingException ex) {
Logger.getLogger(decrypt.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(svbox);
}
}
Thanks!
I guess because it uses the default access modifier.
Java Access Modifiers
The class sun.security.ssl.CipherSuite uses the default access modifier. This means that you can only access this class from the same package, which is not the case in your project.
CipherSuite class definition

Verifying signature of a file using the certificates available in store

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 :)

Cannot find provider error for the supported cipher suite

"TLS_RSA_WITH_AES_128_CBC_SHA256" cipher suite is supported by java 8 default providers. Ref - https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider.
Also I have following program to verify that.
But when I try to get the cipher for the same algorithm it gives error.
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
public class CipherSuitesInfoGenerator {
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException {
SSLContext context = SSLContext.getDefault();
SSLSocketFactory sf = context.getSocketFactory();
String[] cipherSuites = sf.getSupportedCipherSuites();
String cipherName = "TLS_RSA_WITH_AES_128_CBC_SHA256";
for (String s : cipherSuites) {
if (s.equals(cipherName)) {
System.out.println(cipherName + " is supported");
try {
Cipher cipher = Cipher.getInstance(cipherName);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
}
}
}
}
The output is:
TLS_RSA_WITH_AES_128_CBC_SHA256 is supported
Cannot find any provider supporting TLS_RSA_WITH_AES_128_CBC_SHA256
A ciphersuite is something that is used internally in a JSSE provider, it defines the primitives used within the TLS protocol. It's not a Cipher, a Cipher instance in Java represents one primitive used for encryption/decryption such as AES or RSA.

Categories

Resources