java.security.cert.CertificateParsingException - java

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!

Related

Apache Nifi Processor for Signature Verification

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.

Incomplete java.net.URL.openStream() stream

I’m using java.net.URL.openStream() to access a HTTPS resource. The returned stream is incomplete for some URLs: for the example below, it yields a 1,105,724 byte-file whereas the same URL accessed from a browser yields a 5,755,858 byte-file (even when "disabling" Content-Encoding).
And it doesn’t even throw an exception.
What am I missing?
import static java.nio.file.Files.copy;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Paths;
public class Test {
public static void main(String... args) throws IOException {
try (final InputStream in = new URL(
"https://upload.wikimedia.org/wikipedia/commons/9/95/Germany_%28orthographic_projection%29.svg").openStream()) {
copy(in, Paths.get("germany.svg"));
}
}
}
Edit
I’ve tested this code a lot of times (on different networks, but always on JRE 1.8.0_60 / Mac OS X 10.11.4), and sometimes it’s suddenly "starting to work".
However, switching to another of my problematic URLs (e.g. "https://upload.wikimedia.org/wikipedia/commons/c/ce/Andorra_in_Europe_%28zoomed%29.svg") enables me to reproduce the issue.
Does this mean that it is a server issue? I’ve never seen it on a browser though.
It's working fine.
As others have suggested there may be a problem with your network, try connecting to another network.
package test;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class TestMain2 {
public static void main(String[] args) {
System.out.println("Started");
try (final InputStream in = new URL(
"https://upload.wikimedia.org/wikipedia/commons/9/95/Germany_%28orthographic_projection%29.svg")
.openStream()) {
Path outputFile = Paths.get("test.svg");
Files.copy(in, outputFile, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Output file size : " + outputFile.toFile().length());
System.out.println("Finished");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Output
Started
Output file size : 5755858
Finished

Cannot bind jar in xamarin, No packages found

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.

SSLPeerUnverifiedException (Unirest)

I'm new to messing around with APIs (both official and unofficial) and I'm using one called JavaSnap. I've been messing around with a very basic implementation of the example code, but have been running into errors. Here is the very basic code:
Snapchat snapchat = Snapchat.login("xxxx", "xxxxx");
Firstly I ran into loads of ClassNotFound errors and had to keep on downloading apache modules (commons, httpcomponents etc.) to allow the program to progress, but being class files this meant I couldn't see all at once what modules I needed to download. So if anyone wants to tell me how wrong I'm doing something feel free.
Anyway, now having cleared up all the ClassNotFound exceptions (I hope) I'm getting the following exception:
com.mashape.unirest.http.exceptions.UnirestException: javax.net.ssl.SSLPeerUnverifiedException: Host name 'feelinsonice-hrd.appspot.com' does not match the certificate subject provided by the peer (CN=*.appspot.com, O=Google Inc, L=Mountain View, ST=California, C=US)
at com.mashape.unirest.http.HttpClientHelper.request(HttpClientHelper.java:146)
at com.mashape.unirest.request.BaseRequest.asJson(BaseRequest.java:68)
at com.habosa.javasnap.Snapchat.requestJson(Snapchat.java:953)
at com.habosa.javasnap.Snapchat.login(Snapchat.java:160)
at Tester.go(Tester.java:21)
As I understand it, this is because I need to enable trusting all certificates, however to do this I believe I'd need to use HostNameVerifiers with SSLSocketFactorys, but I can't really begin to mess around with this as I only have the source for the JavaSnap API, and tracing the error up the stack the most recent method available for me to edit is this:
private static HttpResponse<JsonNode> requestJson(String path, Map<String, Object> params, File file) throws UnirestException {
MultipartBody req = prepareRequest(path, params, file);
// Execute and return response as JSON
HttpResponse<JsonNode> resp = req.asJson();
// Record
lastRequestPath = path;
lastResponse = resp;
lastResponseBodyClass = JsonNode.class;
return resp;
My question is, am I actually on the right lines with my thinking? If I am how can I achieve my goal of eliminating this error / trusting certificates? If I'm not then what in fact is the problem?
Thanks very much
i answer this old question to remember my search
the certificate error solution is a combination from a few places
https://github.com/Mashape/unirest-java/issues/70, where i started.
http://literatejava.com/networks/ignore-ssl-certificate-errors-apache-httpclient-4-4/ very good explanation.
http://www.baeldung.com/httpclient-ssl, solution for all versions.
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
public class XXX {
private static HttpClient unsafeHttpClient;
static {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
unsafeHttpClient = HttpClients.custom().setSSLContext(sslContext)
.setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
e.printStackTrace();
}
}
public static HttpClient getClient() {
return unsafeHttpClient;
}
public static void main(String[] args) {
try {
HttpClient creepyClient = RestUnirestClient.getClient();
Unirest.setHttpClient(creepyClient);
HttpResponse<JsonNode> response = Unirest.get("https://httpbin.org/get?show_env=1").asJson();
System.out.println(response.getBody().toString());
} catch (UnirestException e) {
e.printStackTrace();
}
}
}

Need to encrypt and decrypt in Java, unable to use Base64... I think

I need to encrypt and decrypt as four digit pin into a database and am having trouble. I have tried using examples that use Base64, put even after importing the package it can't find the class. What am I doing wrong? I understand that the class below may be correct, but why can't it find the class and create an object. In eclipse when I navigate to the Base64 class in reference libraries it says "source not found".
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import org.apache.commons.codec.binary.Base64;
public class PasswordEncryption {
private static Random random = new Random((new Date()).getTime());
public static String encrypt(String userId) {
Base64() encoder = new Base64();
byte[] salt = new byte[8];
random.nextBytes(salt);
return encoder.encode(salt)+
encoder.encode(userId.getBytes());
}
public static String decrypt(String encryptKey) {
if (encryptKey.length() > 12) {
String cipher = encryptKey.substring(12);
BASE64Decoder decoder = new BASE64Decoder();
try {
return new String(decoder.decodeBuffer(cipher));
} catch (IOException e) {
// throw new InvalidImplementationException(
// "Failed to perform decryption for key ["+encryptKey+"]",e);
}
}
return null;
}
}
And apologies if I have not used these forums correctly, this is my first post.
Thanks
I think you need to download Apache Commons Codec. After you've downloaded the jar, you need to add it to your Eclipse project as a library in your build path. (I apologise if you've already done this. It isn't clear from your post.)
Once you've done you still won't be able to see the source in Eclipse, but your project should work when you run it.

Categories