Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

Usually service integrations are via posting JSON or XML. I had a need to integrate with a service that used an HTTP form post. Wait, what? How do you do that? Springframework provides a MultiValueMap interface that is posted as form data. LinkedMultiValueMap is an implementation of the MultiValueMap interface. The MultiValueMap is backed by a LinkedHashMap as opposed to a Map. Hence, it uses add instead of put.

Let’s see it in some code…

MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
// properties that identify our system, etc
map.add("username", username);
map.add("password", password);
map.add("ageToCheck", ageToCheck);
map.add("firstName", kycModel.getFirstName());
map.add("lastName", kycModel.getLastName());
map.add("address", kycModel.getAddress());
map.add("city", kycModel.getCity());
map.add("state", kycModel.getState());
map.add("zip", kycModel.getZip());
map.add("dobMonth", kycModel.getDobMonth());
map.add("dobDay", kycModel.getDobDay());
map.add("dobYear", kycModel.getDobYear());
map.add("ssnLast4", kycModel.getSsnLast4());

Response response = restTemplate.postForObject(url, map, Response.class);

From there on, the RestTemplate works as it normally does.

September 22nd, 2015

Posted In: Java, java ninja, Javaninja, Spring

Tags: , , , ,

Leave a Comment

This seems like a simple thing, but I rarely have the need for a byte[]. Even then, when I do, it is usually an array of binary data and there is no proper String representation of it.

I recently had a case where I had an array of bytes that was stored in the database, but it was actually String data. I started with a person object with a byte[] that I needed to assign into kycModel as a String:

kycModel.setSsnLast4(person.getSsnLast4());

IntelliJ complained that I couldn’t assign a byte[] into a String and suggested I wrap it with a String.valueOf.

kycModel.setSsnLast4(String.valueOf(person.getSsnLast4()));

That still wasn’t good enough. IntelliJ was complaining that there was an implicit call to toString on the byte array. The code compiled correctly, but didn’t work. After a little scouring of the internet I found my solution. String has a constructor that takes a byte[].

kycModel.setSsnLast4(new String(person.getSsnLast4()));

One note about that implementation is that it decodes the byte[] by using the default character set. In Java, this is UTF-8. If you need to specify a characterset, you can use another constructor that takes that value, like the following. Please note, that if you use the constructor that allows you to specify a characterset, then you must also catch UnsupportedEncodingException.

try {
    kycModel.setSsnLast4(new String(person.getSsnLast4(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
    logger.error("", e);
    throw e;
}

September 16th, 2015

Posted In: Java, java ninja, Javaninja

Tags: , ,

Leave a Comment

By hand

Back in the olden days, if you needed a CSV, you would create it by iterating over your data, appending to a String with your separator, then lopping off the last character. Something like this:

StringBuilder messages = new StringBuilder();   
for (String message : kycModel.getMessages()) { 
    messages.append(message).append(",");       
}                                               
myObject.setValue(messages.toString());                        

Apache

Along came Apache Commons and we started using StringUtils.join.

myObject.setValue(StringUtils.join(messages, ","));

Java 8 StringJoiner

Java 8 brought the StringJoiner. The StringJoiner constructor comes in 2 flavors.
new StringJoiner(delimiter)

  • delimeter – the value that will be used to separate the items. The “,” is used for a CSV.

new StringJoiner(delimeter, prefix, suffix)

  • delimeter – The delimeter is the same as the regular constructor.
  • prefix – a character(s) that will be put at the beginning of the sequence (e.g. “[“).
  • suffix – the character(s) that will be placed at the end of the sequence (e.g. “]”).

An example of using the StringJoiner:

StringJoiner stringJoiner = new StringJoiner(",");  
for (String message : kycModel.getMessages()) {     
    stringJoiner.add(message);                      
}                                                   
myObject.setValue(stringJoiner.toString());         

That can be made much easier by using the Java 8 forEach:

StringJoiner stringJoiner = new StringJoiner(",");
kycModel.getMessages().forEach(stringJoiner::add);
myObject.setValue(stringJoiner.toString());

If you really want to squeeze it down further, you can also take advantage of the Java 8 stream

myObject.setValue(kycModel.getMessages().stream().map(String::toString).collect(Collectors.joining(",")));  

September 15th, 2015

Posted In: Java, java ninja, Javaninja, Stream

Tags: , , , , ,

Leave a Comment

The Servlet 3.1 API is retrieved from maven with the following dependency:

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

That is the for API, meaning the specification. If you are doing something and you need an implementation, then you need to grab the implementation for the specific container you are going to be running. The location of the Tomcat 8 implementation is below:

<dependency>
	<groupId>org.apache.tomcat</groupId>
	<artifactId>tomcat-servlet-api</artifactId>
	<version>8.0.26</version>
</dependency>

September 11th, 2015

Posted In: Java, java ninja, Javaninja

Tags: , , , , ,

Leave a Comment

Tomcat is an implementation of the Servlet API. Tomcat 8 is an implementation of the Servlet 3.1 API. The following is an example of the Servlet 3.1 deployment descriptor (web.xml).

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
</web-app>

September 11th, 2015

Posted In: Java, java ninja, Javaninja

Tags: , , , , , , ,

Leave a Comment

Why BCrypt

The big deal is that salting isn’t enough. Processing power has become so plentiful that even a brute force attack can crack salted passwords fairly quickly. BCrypt is slower. It fights processing power with iterations of encryption. This is commonly called the cost factor or work factor. You can configure BCrypt to encrypt multiple times, which causes the decrypt phase to be ran multiple times. The cost factor is used to encrypt the data 2^N times, where N is the cost factor. The default value is typically 10, depending on your implementation. Beware, it has been said on the internet (you know, out there) that a cost factor of 10 is not enough.

How does BCrypt work

BCrypt uses the Blowfish encryption algorithm’s keying schedule with the addition of the work factor. The hashed value that it creates is composed of the following parts, delimited with $:

  • BCrypt algorithm version identifier
  • Cost factor
  • 16-byte salt value, encoded in a modified Base-64 (22 characters)
  • cipher text (remaining characters)

An example hash is:

$21$10$MN9CW1vkR2xSXT8jqchug.wvLZbl4mtapxK0u/SLbTcgl9Ldzlq60

This hash value indicates:

  • BCrypt algorithm version 2a
  • Cost factor of 10
  • Salt is MN9CW1vkR2xSXT8jqchug.
  • the cipher text is wvLZbl4mtapxK0u/SLbTcgl9Ldzlq60

Cost Factor (work factor)

This is the real value of BCrypt. It directly targets the kind of brute force attacks that are so easy to implement with today’s processors. Each increment in the cost factor is exponential (e.g. 2^cost factor). The cost factor is stored as part of the hashed value. This offers the ability to change the cost factor as processing ability increases, without the immediate need to rehash all of the values. When your processors are upgraded, you can run performance tests to determine how many iterations can be performed at an acceptable pace, then update your cost factor. It’s as easy as that.

Flow for updating hashes when the Cost Factor is changed

Let’s consider the case where your processors are upgraded. If the processor upgrade allowed enough of a performance increase to justify that the Cost Factor should be increased, you can immediately start to hash new passwords with the increased Cost Factor. Existing passwords can’t be modified because the hashing is one-way. However, you can update hash values when a user logs in, because you have their plain-text value. If the user authenticates correctly, you can compare the Cost Factor from the pre-existing hash. If it is less than your desired value, you can rehash the password, store it and continue on. The user would not have any indication that you have increased the security of their passwords.

How do you use BCrypt

We use a Java implementation via Spring-security 3.2.5. The BCrypt object offers several methods that make using the API very easy.

One common things that is performed is salt generation. Salt generation is accomplished by calling genSalt. There are several variations of genSalt:

  • genSalt() – Uses the default Cost Factor of 10, uses a new instance of SecureRandom class to generate the 16-byte salt.
  • genSalt(int log_rounds) – Changes the Cost Factor to the value of specified int and uses a new instance of SecureRandom class to generate the 16-byte salt
  • genSalt(int log_rounds, SecureRandom) – Changes the Cost Factor to the value of the specified int. Uses the provided SecureRandom -instance to generate the 16-byte salt.

Once you have a salt, creating the hashed password is just a simple call.

  • hashpw(String password, String salt) – hashes the provided password with the provided salt.

Checking a password is very easy.

  • checkpw(String plaintext, String hashed) – This method will hash the given plain-text value using the salt from the provided hashed value and the provided Cost Factor. If they match, it returns true.

Here is an example of using the API:

String hashed = BCrypt.hashpw(plainTextPassword, BCrypt.gensalt());
//.. store the hash in the database in a <strong>VARBINARY</strong> field.

//.. sometime later, the user attempts to login
if (BCrypt.checkpw(passwordFromLoginPage, hashedValueFromDatabase)) {
    //.. they are authenticated
}

Conclusion

BCrypt is the way to securely store data at the moment. It is easy to customize the amount of processing time required hash a value. This allows you to be as secure as your processors can process and Product Owners want the user’s to wait.

Web page, Author:
Nathan Long, “How can bcrypt have built-in salts?”, StackOverflow.com, edited March 25, 2015, http://stackoverflow.com/questions/6832445/how-can-bcrypt-have-built-in-salts/6833165#6833165

Web page, Author:
Coda Hale, “How To Safely Store A Password”, Codahale.com, updated February 24, 2011, http://codahale.com/how-to-safely-store-a-password/

Web page, Author:
Joseph Wynn, “Bcrypt: Choosing a Work Factor”, http://wildlyinaccurate.com/, updated January 15, 2015, http://wildlyinaccurate.com/bcrypt-choosing-a-work-factor/

September 3rd, 2015

Posted In: Java, java ninja, Javaninja

Tags: , , ,

Leave a Comment

LinkedIn Auto Publish Powered By : XYZScripts.com