Win a copy of Event Streams in Action this week in the Java in General forum!

Mike London

Bartender
+ Follow
since Jul 12, 2002
Cows and Likes
Cows
Total received
17
In last 30 days
0
Total given
0
Likes
Total received
40
Received in last 30 days
0
Total given
2
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Rancher Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Mike London

Abu Alam wrote:This is my first java programming class. When the instructor first told us that we need to use MD5 in our final project, I decided to read up on it, and like you said, everywhere I looked said that same thing, that MD5 is extremely insecure. And trust me, I asked the instructor point blank, " when creating an authentication system, will the MD5 not make it insecure?". The instructor's one word answer to that was "NO". The other thing could be that because it is a beginner level class, the instructor probably just wanted us to be familiar with hash codes. I don't know. But the most I could get out of him about this was a "NO". It also does not help that that it is an online class.



It's not worth arguing with an instructor who may be misinformed or is thinking a certain way that contradicts what is, from my readings, universally agreed upon.

Just do what you need to do to get though the class, as learning how to code is the goal here, and then banish MD5.

-- mike
2 weeks ago

Abu Alam wrote:Cheers Mike. I know what you mean about the MD5. I might be new at java programming, but before I started this project, I did a little research on MD5, and I echoed yours and Tims sentiment to my instructor, and he says that MD5 is not insecure and that the project requirement is using the MD5.

Thank you though.
Abu



You could just point him to many, many of the online resources which discuss the insecurity.

https://en.wikipedia.org/wiki/MD5  (where it says, among other things: "The security of the MD5 hash function is severely compromised")

Nobody I know could survive a code review using MD5 in 2019.

-- mike
2 weeks ago

Abu Alam wrote:I thought I attached the data and the codes.

Anyways, below is the credential data that the program needs to read from

griffin.keyes 108de81c31bf9c622f76876b74e9285f "alphabet soup" zookeeper
rosario.dawson 3e34baa4ee2ff767af8c120a496742b5 "animal doctor" admin
bernie.gorilla a584efafa8f9ea7fe5cf18442f32b07b "secret password" veterinarian
donald.monkey 17b1b7d8a706696ed220bc414f729ad3 "M0nk3y business" zookeeper
jerome.grizzlybear 3adea92111e6307f8f2aae4721e77900 "grizzly1234" veterinarian
bruce.grizzlybear 0d107d09f5bbe40cade3de5c71e9e9b7 "letmein"         admin

username                  hashPW                                             actual PW           role

Below is the MD5 code. I am aware of the insecurity, but it is a requirement of the professor.

import java.security.MessageDigest;

public class MD5Digest {

public static void main(String[] args) throws Exception {
     
     //Copy and paste this section of code
String original = "letmein";  //Replace "password" with the actual password inputted by the user
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(original.getBytes());
byte[] digest = md.digest();
     StringBuffer sb = new StringBuffer();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
     //End copy/paste

System.out.println("original:" + original);
System.out.println("digested:" + sb.toString()); //sb.toString() is what you'll need to compare password strings
}

}

Below is my incomplete code

[code=java]package finalpractice;


import java.security.*;
import java.lang.*;
import java.io.*;
import java.nio.*;
import java.util.*;
import javax.swing.*;

public class FinalPractice
{

 
   public static void main(String[] args) throws FileNotFoundException, IOException, NoSuchAlgorithmException
   {
       //variables from text file
       String userName = "";
       String hashPassword = "";
       String actualPassword = "";
       String employeeRole = "";

       try
       {

           BufferedReader br = new BufferedReader(new FileReader("F:\\SNHU_School\\IT145\\Assignment_codes\\final_project\\Credentials.txt"));
           String line = null;

           while ((line = br.readLine()) != null)
           {
               String tmp[] = line.split("\t");
               userName = tmp[0];
               hashPassword = tmp[1];
               actualPassword = tmp[2];
               employeeRole = tmp[3];
               // print all variables
               // FIXME: REMOVE THE SYSTEM.OUT LINE
               System.out.println(userName + "\t" + hashPassword + "\t" + actualPassword + "\t" + employeeRole);
           }
           br.close();
       }
       catch (IOException FIex)
       {
           System.out.println("ERROR");

       }
       // ASK FOR USERNAME AND PW
       Scanner scnr = new Scanner(System.in);
       String userInputName = "";
       String userInputPW = "";

       System.out.println("Enter username: ");
       userInputName = scnr.next();
       System.out.println("Enter password: ");
       userInputPW = scnr.next();

       
       // GENERATING HASH PW
       //userInputPW = "";
       MessageDigest md = MessageDigest.getInstance("MD5");
       md.update(userInputPW.getBytes());
       byte[] digest = md.digest();
       StringBuilder sb = new StringBuilder();
       for (byte b : digest)
       {
           sb.append(String.format("%02x", b & 0xff));
       }
//FIXME
       System.out.println(sb.toString());
//
       return;
   }
}
When I run the MD5 code with the password in there, the hashed PW it spits out matches the one in the data file, but when I do a test run on my program, a totally different hash is given out. I think it is because for some reason, when the MD5 is taking the user input password, it is disregarding the word after the space. When I enter either of the last to passwords on the data file, the hashed PW matches that of the data file. Although I have removed it from my codes, I did try the split() and replaceAll() methods to get rid of the whitespace in the password before it is fed to the MD5.

The whole program is to write a program for an authentication system, where the user will input username and PW, and if it matches the credentials on the data file, then the user will be given access to another file specific to that user.

Thank you very much for your help Tim.
Abu



What Tim said.

I'd check this site as one of many examples for Generating SHA 256 and I personally would be worried about any class that was teaching me how to use insecure hashing methods like MD5!

https://www.quickprogrammingtips.com/java/how-to-generate-sha256-hash-in-java.html

-- mike
2 weeks ago
Thanks for all the great replies and perspectives!

I'll download Amazon Corretto 11 today.

-- mike
3 weeks ago
I remain confused about whether my clients, and even me, need to buy a $300/year Java SE subscription.

Here are a couple use cases:

1. Customer has a version of Java 8 like 188 installed a year or so ago to run REST services under Tomcat on AWS. Doesn't need upgrades or support from Oracle. Does she need a subscription now?

2. Customer has web apps available to clients on a commercial site with Java 11, but does not need updates or support. Does he need to fork out $300/year?

3. I develop software locally that commercial clients will use. I test that softwarte locally or on my own server, but there is no direct commercial usage of those and only tested by me in isolation. Do I need to fork out $x/year?

---

I've also read that the openjdk, the popular alternative to Oracle's latest shenanigans, isn't always as reliable as the "real thing" from Oracle, but have personally not had any issues with it.

It seems to me that Oracle is trying its best to kill Java, but hopefully I'm just misunderstanding something basic.

Thanks to anyone for help understanding this.

- mike
4 weeks ago

Mike Simmons wrote:The second is correct - at least, it's what most of us would want.  To see what's wrong with the first, add this line:

I get

which is not what we expect for something that should be 0.000000000001.  Unfortunately, that's the sort of thing that can happen when we use the double primitive type.  The solution is to not use the constructor BigDecimal(double) - see the [url=https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigDecimal.html#%3Cinit%3E(double)]API for BigDecimal(double) for an explanation why.  Instead, try using BigDecimal(String):

That should give you what you want...



Thanks very much!

- mike
1 month ago
Using BigDecimal for the simple calculation below, I get one result in Java (and Python). But using an online calculator and another program, I get another result.

Java Code:



Result:

0.000000000000045454545454545453631211255875255243966038341187705575727952898226001045920632102272727272727272727272727272727272727272727272727272727273

----

But, at this website: https://apfloat.appspot.com/

I get a different result:

.000000000001 / 22
0.00000000000004545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545

--

Which is correct and why?

Thanks,

-- mike
1 month ago

Piet Souris wrote:As I wrote in the post I was referring to, the formulas given are usually given in a form that is totally incomprehensible.

Let's define some terms:



Then we have the relation: L = P * a(n, r). or a(n, r) = L / P.

Given n, you can use NR or a binary process to find r. Binary is simple to implement and is usually fast enough. a(n, r) is, given n, a decreasing function in r.



That's useful! I would probably opt for a binary (iterative matching) approach.

F(r) = 1 / (1 + r) ^ n

Can you reproduce Excel's result to get 7.1% with the following Rate() function call using these values:

=RATE(360,-665.30,99000)

7.1%

----

It's a bit unusual to not find a single complete worked example online, anywhere.

Thanks,

-- mike
1 month ago

Paul Clapham wrote:It's possible that the Excel help might include something about which variety or flavour of APR it is implementing.



Good idea, thanks Paul.
1 month ago

Tim Holloway wrote:Hint: That big E-looking symbol is a "for" loop. That's actually a capital Greek "S" (Sigma) and stands for "sum".

Contrary to what a lot of idiots have told me over the years, you don't have to be expert in mathematics to develop software. But it doesn't hurt to learn a little. At a minimum, I recommend getting fluent with algebra and the Calculus of Propositions (symbolic logic).

https://en.wikipedia.org/wiki/Summation#Notation



I have a degree in math; math was not my question.

Just something more basic: What formula is being used?  Solved under what circumstances?

If I need to differentiate a quotient and use Newton's method, I can certainly do that (first semester Calculus, after all).

Thanks,

-- mike
1 month ago

Jim Venolia wrote:Try Wikipedia



Good suggestion.

Unfortunately, there's no example for a simple case I can verify with Excel.

Reading about the potential results' variability and lack of standards only leads to more confusion, sadly.

Thanks,

-- mike
1 month ago
In Excel, LibreOffice, etc., you can calculate the APR like this:

=RATE(360,-665.30,99000)

= 7.1%

---

Yet, wanting to duplicate this result in Java, I have no idea how this is calculated. I downloaded the LibreOffice source code but was unable to find where calc's RATE() function was implemented. (Searching for RATE didn't lead me to the actual logic)

Since I can't find a financial functions library for Java which has RATE() (could have missed it, of course), I need to figure out how to get this result.

I tried using the Newton method to the formula: "P = r × (PV) /(1 − (1 + r) ^ −n)", but the derivative is quite messy as it's a quotient. Not sure this is the optimal approach.

I also tried brute forcing a numerical approximation, but it's unclear if I'm even using the correct formula and what I should be solving for....

Can't find a mathematical discussion/approach/code online as most sites just use Excel.

---

Suggestions would be welcome.

Thanks,

-- mike
1 month ago

Tim Moores wrote:Incidentally, a final version of GraalVM just just released: https://www.infoq.com/news/2019/06/oracle-releases-graalvm-19.0



Interesting.

Since my posting, I figured out how to call a python or R program (not just execute a single line), pass parameters, and get results.

---

Creating a native executable doesn't seem to be much faster than a regular Java program, however.

For example, I have a sample benchmark program that does 2 billion loop iterations. In each iteration, it calls a function to compute a sin(), cos(), and a couple other functions just so the loop is actually doing something.

On an 8-core 2019 iMac (i9), this program (using .parallel()) takes 23 seconds.

Creating a Graal "native-image" that sacrifices byte-code portability for speed, it still takes 22 seconds.

Not much of an improvement.

I'm not motivated at the moment to port this sample program to C, but I bet it would be faster.

- mike

2 months ago