سؤال

I've created a JKS file with public and private RSA keys. When I load this file using external path (like c:/file.jks), the program executes like a charm. However, if I try load this same file from classpath, I got this exception:

java.io.IOException: Invalid keystore format

This is the code used to load the jks:

 KeyStore keyStore = KeyStore.getInstance("JKS");
 InputStream stream=this.getClass().getResourceAsStream("/lutum.jks") ;
 keyStore.load(stream,passe);

the only difference is that I use FileInputStream with full path when loading externally. What I'm doing wrong?

هل كانت مفيدة؟

المحلول

In general your solution should work, provisionally.

What are those provisions? Make sure that your resource folder is in your classpath. If you aren't sure, add it to the -cp flag passed to java when executing your program, or if you are using Eclipse or some other IDE, make sure it is listed as a member of the classpath for that project.

Next, check out this stackoverflow that relates to your question. While the way you are using the class's getResourceAsStream() method is valid (including the / at the start of the filename causes the class resource loader to defer to the ClassLoader's method) it is perhaps less confusing to use the ClassLoader directly. Another good example is found here.

So, first, check that your resources folder is explicitly part of the classpath. Second, prefer the following construction for finding the resource:

InputStream stream= this.class.getClassLoader().getResourceAsStream("lutum.jks");

Note the missing / from the filename. This is because the ClassLoader will automatically start searching at "project root", and the slash will likely just cause issues (if you deploy to JBoss or Tomcat, for instance, that will probably get interpreted by the classloader as an absolute file system path instead of a relative path).

I hope this helps. If not, comment me with more details on your project and I'll alter my answer accordingly.

نصائح أخرى

I suspect that the two keystores are in fact not the same, and that the keystore on the classpath are somehow corrupt.

Try comparing the two keystores. Just read the files into a byte array with something like this:

    public static byte[] streamToByteArray(InputStream is) throws IOException {
        ByteArrayOutputStream tmp = new ByteArrayOutputStream();
        int b = is.read();
        while (b > -1) {
            tmp.write(b);
            b = is.read();
        }
        tmp.flush();
        return tmp.toByteArray();
    }

And then compare them like this:

    InputStream cpStream = this.getClass().getResourceAsStream("/lutum.jks");
    InputStream fileStream = new FileInputStream("c:/file.jks");

    byte[] cpBytes = streamToByteArray(cpStream); 
    byte[] fileBytes = streamToByteArray(fileStream);

    if (Arrays.equals(cpBytes, fileBytes)) {
        System.out.println("They are the same.");
    } else {
        System.out.println("They are NOT the same.");
        // print the file content ...
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top