possibilité de spécifier plusieurs salt, et de fournir le salt en hexadécimal

This commit is contained in:
Jephté Clain 2013-11-19 14:44:10 +04:00
parent cafe570fee
commit 0e9fd3bdf6
1 changed files with 171 additions and 52 deletions

193
upassword
View File

@ -63,6 +63,29 @@ public class upassword {
return sb.toString();
}
public static final boolean isHex(String str) {
int l = str.length();
if (l % 2 != 0) return false;
for (int i = 0; i < l; i++) {
char c = str.charAt(i);
if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f')) {
return false;
}
}
return true;
}
public static final byte[] fromHex(String str) {
if (str == null) return null;
int l = str.length();
byte[] ba = new byte[l / 2];
int j = 0;
for (int i = 0; i < l; i += 2) {
byte b = (byte)Short.parseShort(str.substring(i, i + 2), 16);
ba[j++] = b;
}
return ba;
}
public static final boolean strIsempty(String str) {
return str == null || str.length() == 0;
}
@ -3728,6 +3751,57 @@ public class upassword {
SHA,
SSHA});
private static final Pattern NORMALIZED_FORMAT = Pattern.compile("\\{.+\\}.+");
public static final boolean isNormalizedFormat(String pw) {
return NORMALIZED_FORMAT.matcher(pw).matches();
}
public static final String getNormalizedScheme(String pw) {
if (pw == null) return null;
if (isNormalizedFormat(pw)) {
int p = pw.indexOf('}');
return strSubstr(pw, 1, p).toUpperCase();
} else {
return CLEARTEXT;
}
}
public static final String getNormalizedPassword(String pw) {
if (pw == null) return null;
if (isNormalizedFormat(pw)) {
int p = pw.indexOf('}');
return strSubstr(pw, p + 1);
} else {
return pw;
}
}
public static final boolean isClearScheme(String pw) {
String scheme = getNormalizedScheme(pw);
return strIsempty(scheme) || CLEARTEXT.equals(scheme);
}
public static final boolean isCryptScheme(String pw) {
return CRYPT.equals(getNormalizedScheme(pw));
}
public static final boolean isMd5Scheme(String pw) {
return MD5.equals(getNormalizedScheme(pw));
}
public static final boolean isSmd5Scheme(String pw) {
return SMD5.equals(getNormalizedScheme(pw));
}
public static final boolean isShaScheme(String pw) {
return SHA.equals(getNormalizedScheme(pw));
}
public static final boolean isSshaScheme(String pw) {
return SSHA.equals(getNormalizedScheme(pw));
}
public static final boolean validate(String clear, String normalized) {
return new Password(normalized).validate(clear);
}
@ -3957,12 +4031,6 @@ public class upassword {
return getNormalized();
}
private static final Pattern NORMALIZED_FORMAT = Pattern.compile("\\{.+\\}.+");
private boolean isNormalizedFormat(String pw) {
return NORMALIZED_FORMAT.matcher(pw).matches();
}
public Password setNormalized(String pw) {
reset(true);
if (pw == null) {
@ -4476,32 +4544,42 @@ public class upassword {
// ------------------------------------------------------------------------
private String cryptSalt;
private byte[] sshaSalt;
private byte[] smd5Salt;
private Password getPassword(String clear, String scheme, final String anySalt) {
private Password getPasswordAnySalt(String clear, String scheme, final String anySalt) {
return new Password(clear, scheme) {
@Override
protected String randomCryptSalt() {
String salt = Salt.getCryptSalt(anySalt);
if (salt != null) cryptSalt = salt;
else salt = super.randomCryptSalt();
if (salt == null) salt = super.randomCryptSalt();
return salt;
}
@Override
protected byte[] randomBinarySalt() {
byte[] salt = null;
if (isSshaScheme()) {
salt = Salt.getSshaSalt(anySalt);
if (salt != null) sshaSalt = salt;
} else if (isSmd5Scheme()) {
salt = Salt.getSmd5Salt(anySalt);
if (salt != null) smd5Salt = salt;
if (isSshaScheme()) salt = Salt.getSshaSalt(anySalt);
else if (isSmd5Scheme()) salt = Salt.getSmd5Salt(anySalt);
if (salt == null) salt = super.randomBinarySalt();
return salt;
}
};
}
private Password getPasswordCryptSalt(String clear, String scheme, final String cryptSalt) {
return new Password(clear, scheme) {
@Override
protected String randomCryptSalt() {
String salt = cryptSalt;
if (salt == null) salt = super.randomCryptSalt();
return salt;
}
};
}
private Password getPasswordBinarySalt(String clear, String scheme, final byte[] binarySalt) {
return new Password(clear, scheme) {
@Override
protected byte[] randomBinarySalt() {
byte[] salt = binarySalt;
if (salt == null) salt = super.randomBinarySalt();
return salt;
}
@ -4510,18 +4588,24 @@ public class upassword {
private void run(String[] args) {
if (args.length == 1 && strEquals(args[0], "--help")) {
println("USAGE: upassword [clear [salt]]");
println("USAGE: upassword [clear [salts...]]");
System.exit(0);
}
PasswordGenerator pg = new PasswordGenerator();
Password p;
String clear = null;
if (args.length > 0) clear = args[0];
String salt = null;
if (args.length > 1) salt = args[1];
if (clear == null) clear = pg.generate();
p = getPassword(clear, null, null);
if (clear == null) {
PasswordGenerator pg = new PasswordGenerator();
clear = pg.generate();
}
if (salt == null) {
// Pas de salt, afficher simplement les versions cryptées des mots
// de passe pour tous les schemes
Password p = getPasswordAnySalt(clear, null, null);
String lm = null;
String ntlm = null;
try {
@ -4529,25 +4613,60 @@ public class upassword {
ntlm = p.getNtlmHash();
} catch (Password.NotAvailableException e) {
}
String crypt = getPassword(clear, Password.CRYPT, salt).getNormalized();
String cryptSalt = this.cryptSalt;
String sha = getPassword(clear, Password.SHA, salt).getNormalized();
String ssha = getPassword(clear, Password.SSHA, salt).getNormalized();
String sshaSalt = toHex(this.sshaSalt);
String md5 = getPassword(clear, Password.MD5, salt).getNormalized();
String smd5 = getPassword(clear, Password.SMD5, salt).getNormalized();
String smd5Salt = toHex(this.smd5Salt);
String crypt = getPasswordAnySalt(clear, Password.CRYPT, salt).getNormalized();
String sha = getPasswordAnySalt(clear, Password.SHA, salt).getNormalized();
String ssha = getPasswordAnySalt(clear, Password.SSHA, salt).getNormalized();
String md5 = getPasswordAnySalt(clear, Password.MD5, salt).getNormalized();
String smd5 = getPasswordAnySalt(clear, Password.SMD5, salt).getNormalized();
println("clear: " + clear);
println("lm: " + lm);
println("ntlm: " + ntlm);
println("crypt: " + crypt);
if (cryptSalt != null) println("cryptSalt: " + cryptSalt);
println("sha: " + sha);
println("ssha: " + ssha);
if (sshaSalt != null) println("sshaSalt: " + sshaSalt);
println("md5: " + md5);
println("smd5: " + smd5);
if (smd5Salt != null) println("smd5Salt: " + smd5Salt);
} else {
println("clear: " + clear);
int i = 1, max = args.length;
while (i < max) {
salt = args[i++];
if (Password.isNormalizedFormat(salt)) {
if (Password.isCryptScheme(salt)) {
String cryptSalt = Salt.getCryptSalt(salt);
String crypt = getPasswordCryptSalt(clear, Password.CRYPT, cryptSalt).getNormalized();
println("salt: " + cryptSalt);
println("crypt: " + crypt);
} else if (Password.isSshaScheme(salt)) {
byte[] sshaSalt = Salt.getSshaSalt(salt);
String ssha = getPasswordBinarySalt(clear, Password.SSHA, sshaSalt).getNormalized();
println("salt: " + toHex(sshaSalt));
println("ssha: " + ssha);
} else if (Password.isSmd5Scheme(salt)) {
byte[] smd5Salt = Salt.getSmd5Salt(salt);
String smd5 = getPasswordBinarySalt(clear, Password.SMD5, smd5Salt).getNormalized();
println("salt: " + toHex(smd5Salt));
println("smd5: " + smd5);
} else {
println("salt: " + salt + " !not supported");
}
} else if (isHex(salt)) {
byte[] binarySalt = fromHex(salt);
String ssha = getPasswordBinarySalt(clear, Password.SSHA, binarySalt).getNormalized();
String smd5 = getPasswordBinarySalt(clear, Password.SMD5, binarySalt).getNormalized();
println("salt: " + toHex(binarySalt));
println("ssha: " + ssha);
println("smd5: " + smd5);
} else {
String cryptSalt = Salt.getCryptSalt(salt);
String crypt = getPasswordCryptSalt(clear, Password.CRYPT, cryptSalt).getNormalized();
println("salt: " + cryptSalt);
println("crypt: " + crypt);
}
}
}
System.out.flush();
}