iplanet directory server 에서 파일을 LDIF로 Export하면 사용자 부분에 암호를 입력을 했다면 암호부분은 이상한 글씨가 들어갔을 것이다.
예를 들어 userPassword: {SHA}qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
다음과 같이 나타나 있을 것이다. 이는 다음과 같은 방법으로 만들어 진것이다
그림을 보면
<img src="http://developer.iplanet.com/docs/technote/ldap/password.gif" border=0>
다음과 같다.
암호의 생성과정은 위 그림과 같다.
디렉토리 서버를 인스톨하면 NT일경우 /iplanet/servers/bin/slapd/server에 pwdHASH라는 프로그램이 있다. 이는 {sha}암호를 만드는 프로그램이다.
<b>만들기</b>
C:/>pwdhash -D /iplanet/servers/slapd-hostname -s SHA abc
{SHA}qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
<br><br>
<b>확인</b>
c:/>pwdhash -D /iplanet/servers/slapd-hostname'{SHA} -c qZk+NkcGgWq6PiVxeFDCbJzQ2J0=' abc
pwdhash: password ok.
을 보면 될수 있을 것이다.
위의 기능을 자바로 구현하면
import java.security.MessageDigest; // http://www.javasoft.com/products/jdk/1.1/docs/api/java.security.MessageDigest.html에
import javax.commerce.util.BASE64Encoder; // http://www.javasoft.com/products/commerce/ jecf.jar Java Wallet 1.0 을 설치하면 그 디렉토리에 다음과 같은 jar파일이있다.
import javax.commerce.util.BASE64Decoder;
class pwdSHA {
public static void main (String[] args)
throws java.io.IOException,
java.security.NoSuchAlgorithmException
{
if (args.length < 1) {
String myName = "pwdSHA";
System.out.print (
"usage: " + myName + " [-v] [-s salt] password ...\n" +
" or: " + myName + " [-v] -c digest password ...\n" +
" salt is in hexadecimal notation.\n" +
" digest contains SHA-1 hash and salt, base64 encoded.\n");
return;
}
int i = 0;
boolean verbose = false;
if (args.equals ("-v")) {
++i;
verbose = true;
}
MessageDigest sha = MessageDigest.getInstance ("SHA-1");
if (args.equals ("-c")) { // check passwords against digest
++i;
String digest = args[i++];
if (digest.regionMatches (true, 0, "{SHA}", 0, 5)) {
digest = digest.substring (5); // ignore the label
} else if (digest.regionMatches (true, 0, "{SSHA}", 0, 6)) {
digest = digest.substring (6); // ignore the label
}
BASE64Decoder base64 = new BASE64Decoder();
byte[][] hs = split (base64.decodeBuffer (digest), 20);
byte[] hash = hs[0];
byte[] salt = hs[1];
if (verbose) System.out.println (toHex (hash) + " " +
toHex (salt));
for (; i < args.length; ++i) {
sha.reset();
sha.update (args.getBytes());
sha.update (salt);
byte[] pwhash = sha.digest();
if (verbose) System.out.println (toHex (pwhash));
if (! sha.isEqual (hash, pwhash)) {
System.out.println ("doesn't match: " + args);
}
}
} else { // generate digest from passwords
byte[] salt = {};
if (args.equals ("-s")) {
++i;
salt = fromHex (args[i++]);
if (verbose) System.out.println (toHex (salt));
}
String label = (salt.length > 0) ? "{SSHA}" : "{SHA}";
BASE64Encoder base64 = new BASE64Encoder();
for (; i < args.length; ++i) {
sha.reset();
sha.update (args.getBytes());
sha.update (salt);
byte[] pwhash = sha.digest();
if (verbose) System.out.print (toHex (pwhash) + " ");
System.out.println (label + base64.encode (concatenate (pwhash, salt)));
}
}
}
private static byte[] concatenate (byte[] l, byte[] r) {
byte[] b = new byte [l.length + r.length];
System.arraycopy (l, 0, b, 0, l.length);
System.arraycopy (r, 0, b, l.length, r.length);
return b;
}
private static byte[][] split (byte[] src, int n) {
byte[] l, r;
if (src.length <= n) {
l = src;
r = new byte[0];
} else {
l = new byte[n];
r = new byte[src.length - n];
System.arraycopy (src, 0, l, 0, n);
System.arraycopy (src, n, r, 0, r.length);
}
byte[][] lr = {l, r};
return lr;
}
private static String hexits = "0123456789abcdef";
private static String toHex( byte[] block ) {
StringBuffer buf = new StringBuffer();
for ( int i = 0; i < block.length; ++i ) {
buf.append( hexits.charAt( ( block >>> 4 ) & 0xf ) );
buf.append( hexits.charAt( block & 0xf ) );
}
return buf + "";
}
private static byte[] fromHex( String s ) {
s = s.toLowerCase();
byte[] b = new byte [(s.length() + 1) / 2];
int j = 0;
int h;
int nybble = -1;
for (int i = 0; i < s.length(); ++i) {
h = hexits.indexOf (s.charAt(i));
if (h >= 0) {
if (nybble < 0) {
nybble = h;
} else {
b[j++] = (byte)((nybble << 4) + h);
nybble = -1;
}
}
}
if (nybble >= 0) {
b[j++] = (byte)(nybble << 4);
}
if (j < b.length) {
byte[] b2 = new byte [j];
System.arraycopy (b, 0, b2, 0, j);
b = b2;
}
return b;
}
}
소스를 한번 분석해 보길 바란다. 지금 밖에 프로젝트 나와있는데 이곳에는
Active DIrectory를 쓰고 있더라고요 정말 싫다. MS하하하
|