package org.javastack.sftpserver;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Arrays;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.codec.digest.Sha2Crypt;
public class PasswordEncrypt {
private static final Charset US_ASCII = Charset.forName("US-ASCII");
public final String md5;
public final String apr1; // md5
public final String sha256;
public final String sha512;
public PasswordEncrypt(final String key) {
final byte[] keyBytes = key.getBytes(US_ASCII);
this.md5 = Md5Crypt.md5Crypt(keyBytes.clone());
this.apr1 = Md5Crypt.apr1Crypt(keyBytes.clone());
this.sha256 = Sha2Crypt.sha256Crypt(keyBytes.clone());
this.sha512 = Sha2Crypt.sha512Crypt(keyBytes.clone());
Arrays.fill(keyBytes, (byte) 0);
}
public static boolean isCrypted(final String input) {
if ((input == null) || input.isEmpty())
return false;
if (input.charAt(0) != '$')
return false;
if (input.startsWith("$1$") || // MD5
input.startsWith("$apr1$") || // APR1
input.startsWith("$5$") || // SHA2-256
input.startsWith("$6$")) { // SHA2-512
return true;
}
return false;
}
public static boolean checkPassword(final String crypted, final String key) {
String crypted2 = null;
if (crypted == null)
return false;
if (crypted.length() < 24)
return false;
if (crypted.charAt(0) != '$')
return false;
final int offset2ndDolar = crypted.indexOf('$', 1);
if (offset2ndDolar < 0)
return false;
final int offset3ndDolar = crypted.indexOf('$', offset2ndDolar + 1);
if (offset3ndDolar < 0)
return false;
final String salt = crypted.substring(0, offset3ndDolar + 1);
final byte[] keyBytes = key.getBytes(US_ASCII);
if (crypted.startsWith("$1$")) { // MD5
crypted2 = Md5Crypt.md5Crypt(keyBytes.clone(), salt);
} else if (crypted.startsWith("$apr1$")) { // APR1
crypted2 = Md5Crypt.apr1Crypt(keyBytes.clone(), salt);
} else if (crypted.startsWith("$5$")) { // SHA2-256
crypted2 = Sha2Crypt.sha256Crypt(keyBytes.clone(), salt);
} else if (crypted.startsWith("$6$")) { // SHA2-512
crypted2 = Sha2Crypt.sha512Crypt(keyBytes.clone(), salt);
}
Arrays.fill(keyBytes, (byte) 0);
if (crypted2 == null)
return false;
return crypted.equals(crypted2);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder(16 + md5.length() + apr1.length() + sha256.length()
+ sha512.length());
sb.append("md5=").append(md5).append(' ');
sb.append("apr1=").append(apr1).append(' ');
sb.append("sha256=").append(sha256).append(' ');
sb.append("sha512=").append(sha512);
return sb.toString();
}
public static void main(final String[] args) throws Throwable {
final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String key = null;
if (args.length == 0) {
System.out.println("Enter new password: ");
key = in.readLine().trim();
System.out.println("Retype new password: ");
if (!key.equals(in.readLine().trim())) {
System.out.println("Sorry, passwords do not match");
return;
}
} else {
key = args[0];
if (key.startsWith("-")) {
if (key.equals("-h") || key.equals("--help")) {
System.out.println(PasswordEncrypt.class.getName() + " [<password>]");
return;
}
}
}
final PasswordEncrypt crypt = new PasswordEncrypt(key);
System.out.println(crypt.toString().replace(' ', '\n'));
// Sample:
// plain=changeit
// md5=$1$Ndo.HC0w$ZilSmY0T22G.haCsIKNBq1
// apr1=$apr1$I5GYTkfO$6LN/fWivetFT0avEP9WdI/
// sha256=$5$sVB7PKni$xyo0VYNfaWEqa8lQ5kGbwKogEoQO9w0/b/l.tS1PnUD
// sha512=$6$/aLGYlhc$8Jn6qlvvr5i9lc2CwSCQX1qiAkEbKKfaXbhCjjRueTp4jqN1iM5o9YBJ/7u7VL2hSWE.huvUtsjH1UoVxBRXJ0
}
}