In my application I make use of a p12 certificate file to encrypt traffic when talking to an API I am using.
For my production environment, I need to read these files off the system rather than from the application.
On Linux, how might I read these files off my system into my application into an InputStream just like I would from a resources directory in my application?
I am using Java.
I built a quick and dirty little class to show the opening of a relative .pfx (P12) that I created with keytools. Naturally, you can also look through different potential directories looking for the file, if there are a couple likely places for it to be.
The file structure looks like this:
./bin
./bin/Test.java
./bin/Test.class
./conf
./conf/myFile.pfx
Here's the test code:
import java.io.*;
import java.security.*;
class Test {
public static void main(String[] args) {
String pass = "password";
try {
File file = new File("../conf/myFile.pfx");
InputStream stream = new FileInputStream(file);
KeyStore store = KeyStore.getInstance("PKCS12");
store.load(stream, pass.toCharArray());
PrivateKey key = (PrivateKey)store.getKey("example", pass.toCharArray());
System.out.println("Success");
} catch (KeyStoreException kse) {
System.err.println("Error getting the key");
} catch (Exception e) {
System.err.println("Error opening the key file");
e.printStackTrace();
}
}
}
Related
While writing unit tests for a small component that is part of a relatively massive Java Project, I came across the need to use a method in another class TheOtherClassNoPartOfMyProject that will access a .properties file to fetch values used to set up SSLContext. I managed to get the JAR dependency for this class and attached the source code. Luckily, I can debug the other class which is not part of the component I am developing. Eventually, the method executes the following steps:
public class TheOtherClassNoPartOfMyProject {
...
...
private ResourceBundle resourceBundle = null;
...
...
public void setLocale(Locale newLocale) throws ACCatastrophicException {
if (newLocale.equals(locale) && (resourceBundle != null)) {
return;
}
locale = newLocale;
try {
resourceBundle = ResourceBundle.getBundle(filename, locale);
} catch (MissingResourceException e) {
resourceBundle = null;
System.out.println("Could not locate properties file for locale '"
+ locale.toString() + "'");
throw new ACCatastrophicException("Could not locate "
+ ACProductVersion.getProductName()
+ " properties file for locale '" + locale.toString() + "'");
}
}
...
...
}
The class TheOtherClassNoPartOfMyProject encapsulates the built-in Java Type ResourceBundle to work with .properties files.
When the test runs, I get the error Could not locate properties file for locale ....
Below is to give more context to the problem I am facing.
The component I am writing needs to create SSLContext and must reuse existing common classes I am facing difficulty in how to reuse such classes while writing unit tests since not all dependencies and required properties files are available for the component I am writing.
I have a valid .properties file which works when deployed under the bin folder of the application root folder of the installed application. However, during development time, I don't have a bin folder in my Maven Project and am not sure where to put this .properties file. Below is the code part to create SSLContext in my Maven Project, class MyService:
public class MyService {
...
private static SSLContext sslContext=null;
private static final String TLSV12 = "TLSv1.2";
...
public void createSSLContext() {
KeyStore keyStore= null;
KeyStore trustStore = null;
InputStream kis =null;
InputStream tis = null;
KeyManagerFactory keyManagerFactory = null;
TrustManagerFactory trustManagerFactory = null;
try {
constants = TheOtherClassNoPartOfMyProject.getInstance();
sslContext = SSLContext.getInstance(TLSV12);
if (constants.getString("webservice.keystore") != null && !(constants.getString("webservice.keystore").isEmpty())) {
keyStore = KeyStore.getInstance("JKS");
kis = new FileInputStream(constants.getString("webservce.keystore"));
if (constants.getString("webservice.keystore_password") != null && !(constants.getString("webservice.keystore_password").isEmpty())) {
String keyPassword = "changeit";
keyStore.load(kis,keyPassword.toCharArray());
keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyPassword.toCharArray());
}
}
if (constants.getString("webservice.truststore") !=null && !(constants.getString("webservice.truststore").isEmpty())) {
trustStore = KeyStore.getInstance("JKS");
tis = new FileInputStream(constants.getString("webservice.truststore"));
if (constants.getString("webservice.truststore_password") != null && !(constants.getString("webservice.truststore_password").isEmpty())) {
String trustStorePassword = "changeit";
trustStore.load(tis, trustStorePassword.toCharArray());
}
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
}
sslContext.init(
keyManagerFactory!=null?keyManagerFactory.getKeyManagers():null,
trustManagerFactory!=null?trustManagerFactory.getTrustManagers():null,
new java.security.SecureRandom());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
I was thinking to use mockito to mask such methods, but first I wanted to ensure that the code I am writing will work with the existing dependencies. Also, I still need to research how to use mockit.
Where should I put the .properties file so that it can be picked up by ResourceBundle.getBundle()?
I figured out that I must place the file under src/test/resource or src/main/resources. Also, if you don't qualify the resource name with a package name, then it will look for the file in the base folder of the compiled classes such as target/test-classes. If you qualify the resource name with a package name, it will look for the file in the related folder matching the package name. Note that the file is copied to the relevant folder in the under target/ during compile time.
You can add this test to quickly verify how it works:
public void testResourceBundle() {
ResourceBundle rb = ResourceBundle.getBundle("com.fun.resources.SVCInterface", Locale.getDefault());
System.out.println(rb.getString("some.key"));
assertThat(rb.getString("some.key"), not(isEmptyOrNullString()));
}
Since the above code is running from the test folders, you can place the file under src/test/resource/com/fun/resources and name it SVCInterface.properties and it will work. Make sure it has the key some.key=some-value. In Eclipse, it works since when you run the tests, it will include the target folder of the compiled classes in the classpath by default.
I am trying to access a properties file from the src/main/resources folder but when I try to load the file using a relative path it is not getting updated. But it is working fine for an absolute path.
I need the dynamic web project to work across all platforms.
public static void loadUsers() {
try(
FileInputStream in = new FileInputStream("C:\\Users\\SohamGuha\\Documents\\work-coding\\work-coding\\src\\main\\resources\\users.properties")) {
// write code to load all the users from the property file
// FileInputStream in = new FileInputStream("classpath:users.properties");
users.load(in);
System.out.println(users);
in.close();
}
catch(Exception e){
e.printStackTrace();
}
First of all you are using Spring, at least that is what the tags at the bottom say. Secondly C:\\Users\\SohamGuha\\Documents\\work-coding\\work-coding\\src\\main\\resources\\users.properties is the root of your classpath. Instead of loading a File use the Spring resource abstraction.
As this is part of the classpath you can simply use the ClassPathResource to obtain a proper InputStream. This will work regardless of which environment you are in.
try( InputStream in = new ClassPathResource("users.properties").getInputStream()) {
//write code to load all the users from the property file
//FileInputStream in = new FileInputStream("classpath:users.properties");
users.load(in);
System.out.println(users);
} catch(Exception e){
e.printStackTrace();
}
NOTE: you are already using a try with resources so you don't need to close the InputStream that is already handled for you.
Changing things inside your application simply won't work, as this would mean you could change resources (read classes) in your jar which would be quite a security risk! If you want something to be changable you will have to make it a file outside of the classpath and directly on the file-system.
Try the following code
import java.io.FileInputStream;
import java.io.IOException;
public class LoadUsers {
public static void main(String[] args) throws IOException {
try(FileInputStream fis=new FileInputStream("src/main/resources/users.properties")){
Properties users=new Properties();
users.load(fis);
System.out.println(users);
}catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
I've been trying to save a JSON (currently, it's simply a generic file) to my device's internal storage. I've looked at tons of examples that look exactly like what I've written, but I can never find the file on my device.
Code to save file
public void saveJSONStringToFile(String json) {
FileOutputStream outfile = null;
String filename = "json_test.json";
try {
outfile = openFileOutput(filename, this.MODE_PRIVATE);
outfile.write(json.getBytes());
outfile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I know that it's not working because I've also implemented code to retrieve that file and the app just hangs when I try that, implying that it's looking for something that isn't there.
How to read the values from properties file in java script?
I goggling about it but not satisfied.Please share me some samples or links. My application develops by jsp-servlet, eclipse LUNA and Windows7.
Javascript is executed on the client side and cannot access local files (except the html5 web storage).
If you want to access properties which are defined in a properties file on the server side you have two options:
Server side parsing
Read the properties file at the server side and write the values to the html response as JS values
// output a property as JS value to the client. Make sure this is inside a
// <script> tag
void printProperty(Properties properties, String key) {
Sytem.out.println("var " + key + "='"properties.getProperty("key") + "'");
}
Client side parsing (more complex)
Make the properties file available through an URL (http:/.../conf.properties)
Read the file via ajax
Parse the properties file
You can read property file in many way, below is one of the way. Good Link
config.properties
dbpassword=password
database=localhost
dbuser=mkyong
App.java
package com.mkyong.properties;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class App {
public static void main(String[] args) {
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream("config.properties");
// load a properties file
prop.load(input);
// get the property value and print it out
System.out.println(prop.getProperty("database"));
System.out.println(prop.getProperty("dbuser"));
System.out.println(prop.getProperty("dbpassword"));
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Google Links
i want to copy a file from a server to a client in java.this is my code up to now
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
public class Copy {
private ListDirectory dir = new ListDirectory();
public Copy() {
}
public String getCopyPath(String file) throws Exception {
String path = dir.getCurrentPath();
path += "\\" + file;
return path;
}
public void copyFile(String file) {
try {
File inputFile = new File(dir.getCurrentPath());
URL copyurl;
InputStream outputFile;
copyurl = new URL(getCopyPath(file));
outputFile = copyurl.openStream();
FileOutputStream out = new FileOutputStream(inputFile);
int c;
while ((c = outputFile.read()) != -1)
out.write(c);
outputFile.close();
out.close();
} catch (Exception e) {
System.out.println("Failed to Copy File from server");
e.printStackTrace();
}
}
public static void main(String args[]) {
String a = "put martin";
String b = a.substring(0, 3);
String c = a.substring(4);
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
Problem is , the server is not uploadded online , but it is on my local drive, and the URL thing doesnt work. is there any other way? is this way correct? thanks
If you're expecting to access your file from the local file system (whether that be via network drive or a local disk), you'll need to treat this as if it is a straight file copy.
If you're expecting to access your file as if it is available for download from an HTTP server, you will need to treat it as an HTTP download (which is what it looks like you're trying to do with the URL).
If you want to test the HTTP download functionality using a file on your local system, just set up a simple HTTP server on your dev machine with a directory on your local system, and give your HTTP-downloading code a URL pointing to that local server (on http://localhost, or using your IP address).
Unfortunately, HTTP is a very different animal from a file system, and I don't think there's any way to use the same code to handle both scenarios. If you want your program to ultimately support both protocols, you should build methods/classes to handle both situations, and then have your program detect and use the appropriate protocol for a given path. You'll need to do the same for any other protocol you wish to support (FTP, SFTP, etc).