b4b6e52 Extend PassphraseInfo to return information for common crypt algorithms.
src/sorcerersisle/cfpassphrase/Impl.java | 66 +++++++++++++++++++-
src/sorcerersisle/cfpassphrase/Utils.java | 24 ++++++-
2 files changed, 88 insertions(+), 2 deletions(-)
diff --git a/src/sorcerersisle/cfpassphrase/Impl.java b/src/sorcerersisle/cfpassphrase/Impl.java
index b98171d..30e3d3c 100644
--- a/src/sorcerersisle/cfpassphrase/Impl.java
+++ b/src/sorcerersisle/cfpassphrase/Impl.java
@@ -160,8 +160,72 @@ public final class Impl
return Info;
+ case unix_crypt_md5:
+ Parts = Hash.substring(3).split("\\$");
+
+ Info.put("Algorithm" , "md5crypt" );
+ Info.put("Status" , "Obsolete" );
+
+ Info.put("Salt" , Parts[0] );
+ Info.put("Hash" , Parts[1] );
+
+ return Info;
+
+ case unix_crypt_nthash:
+
+ Info.put("Algorithm" , "NT-Hash" );
+ Info.put("Status" , "Obsolete" );
+
+ Info.put("Hash" , Hash.substring(4) );
+
+ return Info;
+
+ case unix_crypt_sha256:
+ case unix_crypt_sha512:
+ Parts = Hash.substring(1).split("\\$");
+
+ Info.put("Algorithm" , "SHA-2" );
+ Info.put("Version" , Parts[0].equals(5) ? "256" : "512");
+ Info.put("Status" , "Unsupported" );
+
+ if ( Parts[1].startsWith("rounds=") )
+ {
+ Info.put("Rounds" , Parts[1].split("=")[1] );
+ Info.put("Salt" , Parts[2] );
+ Info.put("Hash" , Parts[3] );
+ }
+ else
+ {
+ Info.put("Rounds" , "5000" );
+ Info.put("Salt" , Parts[1] );
+ Info.put("Hash" , Parts[2] );
+ }
+
+ return Info;
+
+ case sun_crypt_md5:
+ Parts = Hash.substring(5).split("\\$");
+
+ Info.put("Algorithm" , "SunMD5" );
+ Info.put("Status" , "Obsolete" );
+
+ if ( Parts[1].startsWith("rounds=") )
+ {
+ Info.put("Rounds" , Parts[0].split("=")[1] );
+ Info.put("Salt" , Parts[1] );
+ Info.put("Hash" , Parts[2] );
+ }
+ else
+ {
+ Info.put("Rounds" , "4096" );
+ Info.put("Salt" , Parts[0] );
+ Info.put("Hash" , Parts[1] );
+ }
+
+ return Info;
+
default:
- throw new Exception("Unsupported Algorithm");
+ throw new Exception("Unknown Algorithm");
}
}
diff --git a/src/sorcerersisle/cfpassphrase/Utils.java b/src/sorcerersisle/cfpassphrase/Utils.java
index 0a4cf47..3a1fe9f 100644
--- a/src/sorcerersisle/cfpassphrase/Utils.java
+++ b/src/sorcerersisle/cfpassphrase/Utils.java
@@ -7,6 +7,13 @@ public final class Utils
public static enum Algorithm
{ bcrypt , pbkdf2 , scrypt
+ // Unimplemented algorithms:
+ , unix_crypt_md5 // $1$
+ , unix_crypt_nthash // $3$
+ , unix_crypt_sha256 // $5$
+ , unix_crypt_sha512 // $6$
+ , sun_crypt_md5 // $md5
+ //
; public static Algorithm fromString(String Str)
{
if ( Str == null ) return DefaultAlgorithm;
@@ -22,7 +29,7 @@ public final class Utils
( String Hash )
throws Exception
{
- if ( Hash.matches("^\\$2a?\\$\\d+\\$[0-9A-Za-z./]+$") )
+ if ( Hash.matches("^\\$2[axy]?\\$\\d+\\$[0-9A-Za-z./]+$") )
return Algorithm.bcrypt;
else if ( Hash.matches("^\\d+:[0-9a-f]+:[0-9a-f]+$") )
@@ -30,6 +37,21 @@ public final class Utils
else if ( Hash.matches("^\\$s0\\$[0-9a-z]+(?:\\$[0-9A-Za-z+=/]+){2}$") )
return Algorithm.scrypt;
+
+ else if ( Hash.matches("^\\$1\\$[0-9A-Za-z./]{8}\\$[0-9A-Za-z./]{22}$") )
+ return Algorithm.unix_crypt_md5;
+
+ else if ( Hash.matches("^\\$3\\$\\$[0-9A-Fa-f]{32}$") )
+ return Algorithm.unix_crypt_nthash;
+
+ else if ( Hash.matches("^\\$5\\$(?:rounds=\\d{1,9}\\$)?[0-9A-Za-z./]{16}\\$[0-9A-Za-z./]{43}$") )
+ return Algorithm.unix_crypt_sha256;
+
+ else if ( Hash.matches("^\\$6\\$(?:rounds=\\d{1,9}\\$)?[0-9A-Za-z./]{16}\\$[0-9A-Za-z./]{86}$") )
+ return Algorithm.unix_crypt_sha512;
+
+ else if ( Hash.matches("^\\$md5(?:[$,]rounds=\\d+)?\\$[./0-9A-Za-z]+\\$[./0-9A-Za-z]+$") )
+ return Algorithm.sun_crypt_md5;
else
throw new Exception("Unknown Algorithm Signature");