I am trying to bind to a very simple jar file in a xamarin android project, but I am getting the warning:
JARTOXML : warning J2X9001: Couldn't load class GetCerts : java.lang.UnsupportedClassVersionError: GetCerts : Unsupported major.minor version 52.0
BINDINGSGENERATOR : warning BG8601: No packages found.
if I add the picasso-2.5.2.jar to the same bindings project, it is accessible perfectly, just as in the documentation for binding a jar from xamarin (http://developer.xamarin.com/guides/android/advanced_topics/java_integration_overview/binding-a-java-library/binding-a-jar/)
the code in the jar is extremely simple:
package com.mgw;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
class GetCerts {
public static X509Certificate GetCert(byte[] bytes) throws Exception
{
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(bytes);
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(in);
return cert;
}
}
Problem was that the class was not public. I changed the code to be:
package com.sage;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
public class GetCerts {
public static X509Certificate GetCert(byte[] bytes) throws Exception
{
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(bytes);
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(in);
return cert;
}
public static boolean DoSomething()
{
return true;
}
}
change the file name to match the class name, rebuilt using JDK6 and it all worked.
Note that the JDK version used to build the library should not be higher than that used by Xamarin or you may get issues.
Related
I have .cer certificate. When I'm opening it, it shows me certificate chain.
Using this code, I read the certificate to x509certificate file.
File certificateFile = new File("C:\\Users\\grish\\Desktop\\certificateForValidation.cer");
InputStream inputStream = new FileInputStream(certificateFile);
X509Certificate certificate = new X509CertImpl(inputStream);
I want to get certificate chain from that file ! (end-entity, CA, Root)
How can I do that programmatically in java.
With C#, this is much more easy
X509Chain ch = new X509Chain();
ch.ChainPolicy.RevocationMode = X509RevocationMode.Online;
ch.Build (certificate);
And then I can get all certificates from ch.
First of all make sure you are using the java.security.cert package; see JDK 17 API doc for java.security.cert.
Avoid using javax.security.cert. The package is marked as deprecated an will be removed in future releases; see JDK 17 API doc for javax.security.cert.
The following code will return a collection of java.security.cert.X509Certificate objects. In the case of your example with the certificate of medium.com the list will contain three items; one for every certificate in the chain.
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.List;
public static void main(String[] args) {
try (InputStream inStream = new FileInputStream("C:\\Users\\grish\\Desktop\\Coding Space\\Certificates\\certificateForValidation.p7b")) {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<X509Certificate> certs = (List<X509Certificate>) cf.generateCertificates(inStream);
} catch (Exception ex) {
ex.printStackTrace();
}
}
I tested it with a PEM formated chain but it should work with PCKS#7 (.p7b file extension) as well; see the documentation of the generateCertificates(InputStream inStream) method.
Find more information about x.509 encoding and conversion here
I have a Quarkus application which implements the server side of a ProtoBuf-over-TLS communications channel and loads a PFX/P12 file at runtime to get the server certificate and private key.
The application runs fine as a when run from the built jar, but when I try running the native image, I get an error indicating that the PKCS12 algorithm cannot be found. It seems like native images expect to have the security artifact pulled-in at build time. Do I have this correct? Is there any way to work-around this?
Example code:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.runtime.annotations.QuarkusMain;
#QuarkusMain
public class KeystoreTest implements QuarkusApplication {
String keystoreFile = "/home/sm-dp/... server.pfx";
String keystoreSecret = "secret";
#Override
public int run(String... args) throws Exception {
KeyStore keystore = KeyStore.getInstance("PKCS12");
try (InputStream fis = new FileInputStream(new File(keystoreFile))) {
keystore.load(fis, keystoreSecret.toCharArray());
}
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX");
keyManagerFactory.init(keystore, keystoreSecret.toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
return 0;
}
}
Stacktrace:
java.security.KeyStoreException: PKCS12 not found
at java.security.KeyStore.getInstance(KeyStore.java:851)
at com.mcleodnet.KeystoreTest.run(KeystoreTest.java:21)
at com.mcleodnet.KeystoreTest_ClientProxy.run(KeystoreTest_ClientProxy.zig:157)
at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:112)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:61)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:38)
at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:30)
Caused by: java.security.NoSuchAlgorithmException: class configured for KeyStore (provider: SunJSSE) cannot be found.
at java.security.Provider$Service.getImplClass(Provider.java:1649)
at java.security.Provider$Service.newInstance(Provider.java:1592)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:164)
at java.security.Security.getImpl(Security.java:695)
at java.security.KeyStore.getInstance(KeyStore.java:848)
... 6 more
Caused by: java.lang.ClassNotFoundException: sun.security.pkcs12.PKCS12KeyStore
at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:60)
at java.lang.Class.forName(DynamicHub.java:1194)
at java.security.Provider$Service.getImplClass(Provider.java:1634)
... 11 more
Try to add quarkus.native.enable-all-security-services=true to your configuration.
If it's not working, you can add a #RegisterForReflection(targets = sun.security.pkcs12.PKCS12KeyStore.class) to one of your application class.
I have developed a JAVA application for signature verification as follows:
package read_key_pck;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.util.Scanner;
import javax.xml.bind.DatatypeConverter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class Main {
public final static String RESOURCES_DIR = "C:\\Users\\KX5710\\eclipse-workspace\\read_key\\src\\read_key_pck\\";
public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {
Signature publicSignature = Signature.getInstance("SHA256withRSA");
publicSignature.initVerify(publicKey);
publicSignature.update(plainText.getBytes(UTF_8));
byte[] signatureBytes = DatatypeConverter.parseHexBinary(signature);
return publicSignature.verify(signatureBytes);
}
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
PublicKey pub = null;
KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
try {
pub = generatePublicKey(factory, RESOURCES_DIR
+ "rsa_2048_pub.pem");
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
String encodedPublicKey = Base64.getEncoder().encodeToString(pub.getEncoded());
System.out.println("publickey: " + encodedPublicKey);
boolean isCorrect = verify(" 4 5.00 1.80", "54c5645616a8567d605bd990df0456913420fb630860316cf29bf57e19ef3102933ac948e672a4e3dfa8b7e20cc9eb44520aa8d8dc69143a5bc718a17a1d3f2dfc0084f172dbda6dd38e411e75100136d95d46e3d563c3a0aed062c40c6d17a5038ef0ad681622245bd2332008b1edca693b3418df1f5f86f09a6585d4af7da0d2ab44f5ce1c7ec8eed51696697b2674a881868be7163eda7c6562d02bdf069fcd66d483e8b22c5c976d27c04ffe38e62800eec17f1786b2f2161fcf44b91ba85a4486edb48a5c5a2f58dc1fa3969917eadabd7af753947de4a7f03034de09adb3b1cacb77e21444eee2d90944037606f84d0aa99f4794e8df8a2d0fbfff55c7", pub);
System.out.println("Signature verification: " + isCorrect);
}
private static PublicKey generatePublicKey(KeyFactory factory,
String filename) throws InvalidKeySpecException,
FileNotFoundException, IOException {
PemFile pemFile = new PemFile(filename);
byte[] content = pemFile.getPemObject().getContent();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
return factory.generatePublic(pubKeySpec);
}
}
package read_key_pck;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
public class PemFile {
private PemObject pemObject;
public PemFile(String filename) throws FileNotFoundException, IOException {
PemReader pemReader = new PemReader(new InputStreamReader(
new FileInputStream(filename)));
try {
this.pemObject = pemReader.readPemObject();
} finally {
pemReader.close();
}
}
public PemObject getPemObject() {
return pemObject;
}
}
Now I want to develop an Apache Nifi Processor for this JAVA application; I have a sample code here :
https://github.com/pcgrenier/nifi-examples
However I do not know that I have to modify which parts of this sample code, since it is the first time i develop an Apache Nifi Processor.
Also When I want to run .bat file in cmd i.e. run-nifi.bat I get this error :
"The JAVA_HOME environment variable is not defined correctly. Instead
the PATH will be used to find the java executable."
Here is detailed guide for beginners https://community.hortonworks.com/articles/4318/build-custom-nifi-processor.html .
The above article is based on this video https://www.youtube.com/watch?v=3ldmNFlelhw
Briefly explanation:
You should create the new project from one of the NiFi maven archetype.
Modify generated processor to your needs.
Build the nar file and put it to NiFi.
Use it in NiFi.
Great that you're writing your own custom processor on NiFi. Couple of things that you have to keep in mind:
The core functionality that your processor intends to do goes inside the overridden onTrigger method.
Handling relationships of your processor (Failure/Success)
Couple of guides that would help in your quest:
http://www.nifi.rocks/developing-a-custom-apache-nifi-processor-json/
https://bryanbende.com/development/2015/02/04/custom-processors-for-apache-nifi
The first one provides you some overview on common terminologies & functionalities in the form of annotation and classes that are widely used in NiFi processors and also provide relevant links to the same on Apache NiFi developer guide. That tutorial itself should be able to get you started with the actual implementation since it has examples in the form of code and POM.
I'm getting the following exception when trying to create a new certificate:
java.security.cert.CertificateParsingException: signed overrun, bytes = 224
try
{
InputStream certificateStream = new ByteArrayInputStream(certificate);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Collection certificateCollection = cf.generateCertificates(certificateStream);
}
catch (CertificateException ex)
{
}
the exception is thrown in:
Collection certificateCollection = cf.generateCertificates(certificateStream);
can someone help me to understand and solve this issue?
Thanks
Here is a well-functioning example based on your code. It uses a FileInputStream. If you use a ByteArray, be careful of the data within it :
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.io.FileNotFoundException;
public class StackOverflow {
public static void main(String[] args) throws FileNotFoundException, CertificateException {
InputStream certificateStream = new FileInputStream("stackoverflow.cert");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Collection certificateCollection = cf.generateCertificates(certificateStream);
}
}
Ok, my mistake.
I read the certificate from file, and I didn't read it as binary...
Reading as binary solved this issue.
Thanks alot for all your answers / comments!
I would like to be able to get access to all trusted root certificates programmatically in a Java app.
I was looking at the keystore interface, but I'm hoping to get the list of trusted roots that's implicit with the JRE.
Is this accessible anywhere?
There's an example that shows how to get a Set of the root certificates and iterate through them called Listing the Most-Trusted Certificate Authorities (CA) in a Key Store. Here's a slightly modified version that prints out each certificate (tested on Windows Vista).
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
try {
// Load the JDK's cacerts keystore file
String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar);
FileInputStream is = new FileInputStream(filename);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
String password = "changeit";
keystore.load(is, password.toCharArray());
// This class retrieves the most-trusted CAs from the keystore
PKIXParameters params = new PKIXParameters(keystore);
// Get the set of trust anchors, which contain the most-trusted CA certificates
Iterator it = params.getTrustAnchors().iterator();
while( it.hasNext() ) {
TrustAnchor ta = (TrustAnchor)it.next();
// Get certificate
X509Certificate cert = ta.getTrustedCert();
System.out.println(cert);
}
} catch (CertificateException e) {
} catch (KeyStoreException e) {
} catch (NoSuchAlgorithmException e) {
} catch (InvalidAlgorithmParameterException e) {
} catch (IOException e) {
}
}
}
This should be more flexible using the default trust store in the system to get all certificates:
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
List<Certificate> x509Certificates = new ArrayList<>();
trustManagerFactory.init((KeyStore)null);
Arrays.asList(trustManagerFactory.getTrustManagers()).stream().forEach(t -> {
x509Certificates.addAll(Arrays.asList(((X509TrustManager)t).getAcceptedIssuers()));
});
```
A working example, combining concept from Bill the Lizard and k_o_ answer:
import java.io.FileInputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class JDKTrustStoreCertListing {
public static void main(String[] args) throws Exception{
String javaHome=System.getProperty("java.home");
Path jdkCACertPath=Paths.get(javaHome, "lib", "security", "cacerts");
TrustManagerFactory trustManagerFactory=TrustManagerFactory
.getInstance(TrustManagerFactory
.getDefaultAlgorithm());
FileInputStream fis=new FileInputStream(jdkCACertPath.toFile());
String keystorePassword="changeit";
KeyStore keyStore=KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(fis, keystorePassword.toCharArray());
fis.close();
trustManagerFactory.init(keyStore);
TrustManager[] truestManagers=trustManagerFactory.getTrustManagers();
for(TrustManager t:truestManagers)
for(X509Certificate c:((X509TrustManager)t).getAcceptedIssuers())
System.out.println(c.getIssuerX500Principal());
}//main closing
}//class closing