For making the database connection in spring 3 i use xml which have defined bean
<bean id="griffDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" p:driverClass="${DRIVER_CLASS}" p:jdbcUrl="${DB_URL}"
p:minPoolSize="${MIN_DB_POOL_SIZE}" p:maxPoolSize="${DB_POOL_SIZE}"
p:maxStatements="${DB_POOL_SIZE}"p:idleConnectionTestPeriod="${IDLE_CONNECTION_TEST_PERIOD}"p:loginTimeout="${LOGIN_TIMEOUT}" scope="singleton"></bean>
here DB_URL value is read from property file
DB_URL:jdbc:mysql://localhost:3306/databaseautoReconnect=true&user=root&password= [B#42e21073
This password in url is encrypted using AES.
The requirement is that i should write a code that when spring go for making the connection to the database it should itself decrypt the password and make the connection.
How can i achieve that?
I have used BASE64Encoder & BASE64Decoder. later You will modify my code to use a secure/better encryption/decryption algorithm.
You first encoded your database password by using the below code:
private String encode(String str) {
BASE64Encoder encoder = new BASE64Encoder();
str = new String(encoder.encodeBuffer(str.getBytes()));
return str;
}
Now You use wrapper class for org.apache.commons.dbcp.BasicDataSource and overridden setPassword() method:
import java.io.IOException;
import org.apache.commons.dbcp.BasicDataSource;
import sun.misc.BASE64Decoder;
public class MyCustomBasicDataSource extends BasicDataSource{
public synchronized void setPassword(String encodedPassword){
this.password = decode(encodedPassword);
}
private String decode(String password) {
BASE64Decoder decoder = new BASE64Decoder();
String decodedPassword = null;
try {
decodedPassword = new String(decoder.decodeBuffer(password));
} catch (IOException e) {
e.printStackTrace();
}
return decodedPassword;
}
}
This way You can decoding(BASE64Decoder) the encoded password .
Related
I need some guidance on the scenario where I need to check the password coming from UI form (i.e, Authentication object) which I need to hashed using SHA-256 + constant salt(before making comparison) and password coming from DB (DB also has hashed password + salt) using Spring Security.
I am looking to compare these two different hashed value generated using same SALT value. How we can do it in java? Could anyone please share me a sample code?
You could simply compare the two password strings passwordA.equals(passwordB) ...
This has some security shortcomings:
Passwords should not be handled as strings, but as char or byte arrays: see here why
An Equal comparison is (theoretically) vulnerable to a timing-attack: see a discussion about a solution in java
It might be wise to use standard-tool to do security related things (even when they seem to be simple). Spring security has a ton of tools that can do that for you. Have a look at BCryptPasswordEncoder for example. Using well tested and maintained frameworks for security purposes is always a good idea.
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(password);
...
boolean result = passwordEncoder.matches(rawPassword, hashedPassword);
Also: Use a proper Algorithm for Password-Hashing! See this Answer on SO for some proposals
SHA-256 is not one of them. Spring Security gives you the right tools for the jobs, so you could just use them.
It looks to me you're looking to compare two separate hashed values created using same salt. Am I right ? If yes, so here is the sample program taking a reference from https://ashishpshukla.wordpress.com/2010/07/02/sample-java-code-for-password-encryption-using-secure-hash-algorithm-sha-256/
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class PasswordEncoder {
private static PasswordEncoder instance;
private final static int ITERATION_COUNT = 5;
private PasswordEncoder() { }
public static synchronized PasswordEncoder getInstance() {
if (instance == null) {
PasswordEncoder returnPasswordEncoder = new PasswordEncoder();
return returnPasswordEncoder;
}
else
return instance;
}
public synchronized String encode(String password, String saltKey)throws NoSuchAlgorithmException, IOException {
String encodedPassword = null;
byte[] salt = base64ToByte(saltKey);
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.reset();
digest.update(salt);
byte[] btPass = digest.digest(password.getBytes("UTF-8"));
for (int i = 0; i < ITERATION_COUNT; i++) {
digest.reset();
btPass = digest.digest(btPass);
}
encodedPassword = byteToBase64(btPass);
return encodedPassword;
}
private byte[] base64ToByte(String str) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
byte[] returnbyteArray = decoder.decodeBuffer(str);
return returnbyteArray;
}
private String byteToBase64(byte[] bt) {
BASE64Encoder endecoder = new BASE64Encoder();
String returnString = endecoder.encode(bt);
return returnString;
}
public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
String password = "Secrete#343";
String saltKey = "PveFT7isDjGYFTaYhc2Fzw==";
String hash1,hash2 = null;
// Assume from UI
PasswordEncoder encoder1 = PasswordEncoder.getInstance();
hash1 = encoder1.encode(password, saltKey);
System.out.println(hash1);
// Assume the same present in db
PasswordEncoder encoder2 = PasswordEncoder.getInstance();
hash2 = encoder2.encode(password, saltKey);
System.out.println(hash2);
if(hash1.equalsIgnoreCase(hash2))
System.out.println("Both hash Matches..");
else
System.out.println("Hash matches fails..");
}
}
The output:
8WgbLik5EbdtJY4OWm2ZQ0tHiU2lmvXNVrPhFDz3W2Y=
8WgbLik5EbdtJY4OWm2ZQ0tHiU2lmvXNVrPhFDz3W2Y=
Both hash Matches..
I'm using the Jackrabbit library for communicating with a cloud storage using the webdav protocol. I need a way to list all files from a specific directory and get the last modified property but I can't seem to find any working examples on this.
I basically need code to synchronize files from the local directory with the webdav url.
import java.io.File;
import java.io.FileInputStream;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.jackrabbit.webdav.client.methods.DavMethod;
import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
import org.apache.jackrabbit.webdav.client.methods.PutMethod;
public class WebDavClient
{
private String resourceUrl;
private HttpClient client;
private Credentials credentials;
private DavMethod method;
public WebDavClient(String resourceUrl, String username, String password)
throws Exception
{
this.resourceUrl = resourceUrl;
client = new HttpClient();
credentials = new UsernamePasswordCredentials(username, password);
client.getState().setCredentials(AuthScope.ANY, credentials);
}
public int upload(String fileToUpload) throws Exception
{
method = new PutMethod(getUpdatedWebDavPath(fileToUpload));
RequestEntity requestEntity = new InputStreamRequestEntity(
new FileInputStream(fileToUpload));
((PutMethod) method).setRequestEntity(requestEntity);
client.executeMethod(method);
return method.getStatusCode();
}
public int createFolder(String folder) throws Exception
{
method = new MkColMethod(getUpdatedWebDavPath(folder));
client.executeMethod(method);
return method.getStatusCode();
}
private String getUpdatedWebDavPath(String file)
{
// Make sure file names do not contain spaces
return resourceUrl + "/" + new File(file).getName().replace(" ", "");
}
}
Usage example for uploading the file Test.txt to the Backup folder:
String myAccountName = "...";
String myPassword = "...";
WebDavClient webdavUploader = new WebDavClient("https:\\\\webdav.hidrive.strato.com\\users\\" + myAccountName + "\\Backup", myAccountName, myPassword);
webdavUploader.upload("C:\\Users\\Username\\Desktop\\Test.txt");
Here's a list of different DavMethods that could be helpful:
http://jackrabbit.apache.org/api/1.6/org/apache/jackrabbit/webdav/client/methods/package-summary.html
Please help, I'm been struggling on this for so long!
Take a look at the AMES WebDAV Client code from Krusche and Partner on the EU portal. It is licensed under GPL, so should it may fit your purpose.
https://joinup.ec.europa.eu/svn/ames-web-service/trunk/AMES-WebDAV/ames-webdav/src/de/kp/ames/webdav/WebDAVClient.java
It works for me, though to access e.g. Win32LastModifiedTime I need to get the custom namespace, e.g.
private static final Namespace WIN32_NAMESPACE = Namespace.getNamespace("Z2", "urn:schemas-microsoft-com:");
and retrieve the custom Property Win32LastModifiedTime from the properties.
/*
* Win32LastModifiedTime
*/
String win32lastmodifiedtime = null;
DavProperty<?> Win32LastModifiedTime = properties.get("Win32LastModifiedTime", WIN32_NAMESPACE);
if ((Win32LastModifiedTime != null) && (Win32LastModifiedTime.getValue() != null)) win32lastmodifiedtime = Win32LastModifiedTime.getValue().toString();
I want to read property file on Server side. I have DBConfig.java, useDBConfig.java and DBConfig.properties all placed in server package. I can't read the values from property file on Server Side. Your help is highly appreciated.
public interface DBConfig extends Constants {
#DefaultStringValue("host")
String host(String host);
#DefaultStringValue("port")
String port(String port);
#DefaultStringValue("username")
String username(String username);
#DefaultStringValue("password")
String password(String password);
}
public void useDBConfig() {
DBConfig constants = GWT.create(DBConfig.class);
Window.alert(constants.host());
host = constants.host(host);
port = constants.port(port);
username = constants.username(username);
password = constants.password(password);
}
property file...
host=127.0.0.1
port=3306
username=root
password=root
Thanks in advance.
GWT.Create can be used only in client mode.
Are you sure that code execute in server side?
If i write in my application GWT.Create in server side i get this error:
java.lang.UnsupportedOperationException: ERROR: GWT.create() is only usable in client code! It cannot be called, for example, from server code. If you are running a unit test, check that your test case extends GWTTestCase and that GWT.create() is not called from within an initializer or constructor.
You can read a properties files in java. The file is similar that Constants files in GWT.
Example of Properties file:
key = value
host = 127.0.0.1
port = 80
username = guest
password = guest
EOF
You can read this file, see the next code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
String fileToRead = "MY_PATH"+File.separator+"MY_FILE.properties";
Properties prop = new Properties();
try {
File propertiesFile = new File(fileToRead);
prop.load(new FileInputStream(propertiesFile));
String host = prop.getProperty("host");
String port = prop.getProperty("port");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
System.out.println(host);
System.out.println(port);
System.out.println(username);
System.out.println(password);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
If the key doesnt exists getProperty(String key) return null.
You can use prop.containsKey(String key); to see if the key exists. This function return a boolean (True if exists False in other case).
Greetings
I have imported this library http://raginggoblin.wordpress.com/2012/08/11/java-alternative-to-php-crypt-function/, in to my project but yet unable to use the class named "crypt" to encrypt string by passing password and salt to crypt method in it.
public class JavaApplication6 {
public static void main(String[] args) {
// TODO code application logic here
String password = "rasmuslerdorf";
String salt = "$6$rounds=5000$usesomesillystringforsalt$";
String encrypted = Crypt.crypt(password, salt);
System.out.println(""+encrypted);
}
}
this is the imported library contains,
Based on your posted code, I suspect you aren't getting the correct Crypt. I suggest you use a static import and change this,
String encrypted = Crypt.crypt(password, salt);
to
String encrypted = crypt(password, salt);
or you might use,
String encrypted = raging.goblin.crypt.Crypt.crypt(password, salt);
And the static import would be,
static import raging.goblin.crypt.Crypt.crypt;
Finally your image tells me you got the src jar, the way you're using it you want the binary jar.
Currently, the only way I know to retrieve the administrator password from a newly created EC2 windows instance is through the AWS management console. This is fine, but I need to know how to accomplish this via the Java API - I can't seem to find anything on the subject. Also, once obtained, how do I modify the password using the same API?
The EC2 API has a call "GetPasswordData" which you can use to retrieve an encrypted block of data containing the Administrator password. To decrypt it, you need 2 things:
First, the private key. This is the private half of the keypair you used to instantiate the instance. A complication is that normally Amazon uses keys in PEM format ("-----BEGIN"...) but the Java Crypto API wants keys in DER format. You can do the conversion yourself - strip off the -----BEGIN and -----END lines, take the block of text in the middle and base64-decode it.
Second, the encryption parameters. The data is encrypted with RSA, with PKCS1 padding – so the magic invocation to give to JCE is: Cipher.getInstance("RSA/NONE/PKCS1Padding")
Here's a full example (that relies on BouncyCastle, but could be modified to use a different crypto engine)
package uk.co.frontiertown;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.GetPasswordDataRequest;
import com.amazonaws.services.ec2.model.GetPasswordDataResult;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import javax.crypto.Cipher;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
public class GetEc2WindowsAdministratorPassword {
private static final String ACCESS_KEY = "xxxxxxxxxxxxxxxxxxxx";
private static final String SECRET_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
private static final String PRIVATE_KEY_MATERIAL = "-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIEowIBAAKCAQEAjdD54kJ88GxkeRc96EQPL4h8c/7V2Q2QY5VUiJ+EblEdcVnADRa12qkohT4I\n" +
// several more lines of key data
"srz+xXTvbjIJ6RL/FDqF8lvWEvb8uSC7GeCMHTznkicwUs0WiFax2AcK3xjgtgQXMgoP\n" +
"-----END RSA PRIVATE KEY-----\n";
public static void main(String[] args) throws GeneralSecurityException, InterruptedException {
Security.addProvider(new BouncyCastleProvider());
String password = getPassword(ACCESS_KEY, SECRET_KEY, "i-XXXXXXXX", PRIVATE_KEY_MATERIAL);
System.out.println(password);
}
private static String getPassword(String accessKey, String secretKey, String instanceId, String privateKeyMaterial) throws GeneralSecurityException, InterruptedException {
// Convert the private key in PEM format to DER format, which JCE can understand
privateKeyMaterial = privateKeyMaterial.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
privateKeyMaterial = privateKeyMaterial.replace("-----END RSA PRIVATE KEY-----", "");
byte[] der = Base64.decode(privateKeyMaterial);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(der);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// Get the encrypted password data from EC2
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
AmazonEC2Client client = new AmazonEC2Client(awsCredentials);
GetPasswordDataRequest getPasswordDataRequest = new GetPasswordDataRequest().withInstanceId(instanceId);
GetPasswordDataResult getPasswordDataResult = client.getPasswordData(getPasswordDataRequest);
String passwordData = getPasswordDataResult.getPasswordData();
while (passwordData == null || passwordData.isEmpty()) {
System.out.println("No password data - probably not generated yet - waiting and retrying");
Thread.sleep(10000);
getPasswordDataResult = client.getPasswordData(getPasswordDataRequest);
passwordData = getPasswordDataResult.getPasswordData();
}
// Decrypt the password
Cipher cipher = Cipher.getInstance("RSA/NONE/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] cipherText = Base64.decode(passwordData);
byte[] plainText = cipher.doFinal(cipherText);
String password = new String(plainText, Charset.forName("ASCII"));
return password;
}
}
ObDisclosure: I originally answered this on a blog posting at http://www.frontiertown.co.uk/2012/03/java-administrator-password-windows-ec2-instance/
You can create an instance, set the password and then turn it back into an image. Effectively setting a default password for each instance you create. Wouldn't this be simpler?
Looks like you are looking for the following parts of the API: GetPasswordDataRequest and GetPasswordDataResult
You can also create a Image with default user name and Password setup on that Image.And then launch all instances with that image id..so that you dont need to create and retrieve password evry time..just launch your instance rdp that launched instance with definde credntials in Image. I am doing same.And its perfectly working for me.