001: package org.esupportail.cas.server.util.crypt;
002:
003: import jcrypt.jcrypt;
004: import md5.MD5;
005: import md5.MD5Crypt;
006:
007: /**
008: * This class offers encryption methods used by handlers encrypting
009: * users' passwords and comparing them to a reference (file or
010: * database).
011: *
012: * @author Jean-Baptiste Daniel <danielj at sourceforge.net>
013: */
014: public abstract class Crypt {
015:
016: /**
017: * An array containing the encryptions supported by the module.
018: */
019: private static String[] supportedEncryptions = { "plain", "des",
020: "md5", "pammd5" };
021:
022: /**
023: * Tell if an encryption is supported.
024: * @param encryption an encryption
025: *
026: * @return true if the encryption is supported, false otherwise.
027: */
028: public static boolean isEncryptionSupported(final String encryption) {
029: if (encryption.equals("plain")) {
030: return true;
031: }
032: if (encryption.equals("des")) {
033: return true;
034: }
035: if (encryption.equals("md5")) {
036: return true;
037: }
038: if (encryption.equals("pammd5")) {
039: return true;
040: }
041: return false;
042: }
043:
044: /**
045: * Compare a password with its encryption using an encryption method.
046: *
047: * @param encryption an encryption method (must be supported)
048: * @param password the password
049: * @param encryptedPassword the encrypted password
050: *
051: * @return true if password matches, false otherwise
052: * @throws Exception when encryption is not supprted.
053: */
054: public static boolean match(final String encryption,
055: final String password, final String encryptedPassword)
056: throws Exception {
057: if (encryption.equals("plain")) {
058: return encryptedPassword.equals(password);
059: }
060: if (encryption.equals("des")) {
061: return matchDES(password, encryptedPassword);
062: }
063: if (encryption.equals("md5")) {
064: return matchMD5(password, encryptedPassword);
065: }
066: if (encryption.equals("pammd5")) {
067: return matchPAMMD5(password, encryptedPassword);
068: }
069: throw new Exception("Unsupported encryption method.");
070: }
071:
072: /**
073: * Retrieve the salt of an MD5 encrypted string.
074: *
075: * @param encryptedString an MD5 encrypted string
076: *
077: * @return the salt of the encrypted string, or null on error.
078: */
079: private static String getMD5Salt(final String encryptedString) {
080:
081: try {
082: return encryptedString.split("\\$")[2];
083: } catch (Exception e) {
084: return null;
085: }
086: }
087:
088: /**
089: * MD5 Encryption of a string using a salt.
090: *
091: * @param password the password to encrypt
092: * @param salt the salt to encrypt with
093: *
094: * @return the encrypted string (null if the salt is null).
095: */
096: private static String cryptMD5(final String password,
097: final String salt) {
098: if (salt == null) {
099: return null;
100: }
101: return MD5Crypt.crypt(password, salt);
102: }
103:
104: /**
105: * MD5 comparison.
106: *
107: * This method compares a clear password with a MD5 hash as created
108: * by 'md5sum' or MySQL's 'MD5()'.
109: *
110: * @param password a clear password.
111: * @param encryptedPassword an already encrypted password.
112: *
113: * @return true if password matches, false otherwise.
114: */
115: private static boolean matchMD5(final String password,
116: final String encryptedPassword) {
117: return encryptedPassword.equals(MD5.md5crypt(password));
118: }
119:
120: /**
121: * Linux PAM MD5 comparison.
122: *
123: * This method compares a clear password with a Linux PAM / OpenBSD
124: * / FreeBSD compatible md5-encoded password hash.
125: *
126: * @param password a clear password.
127: * @param encryptedPassword an already encrypted password.
128: *
129: * @return true if password matches, false otherwise.
130: */
131: private static boolean matchPAMMD5(final String password,
132: final String encryptedPassword) {
133: return encryptedPassword.equals(cryptMD5(password,
134: getMD5Salt(encryptedPassword)));
135: }
136:
137: /**
138: * Retrieve the salt of a DES encrypted string.
139: *
140: * @param encryptedString a DES encrypted string
141: *
142: * @return the salt of the encrypted string, or null on error.
143: */
144: private static String getDESSalt(final String encryptedString) {
145:
146: try {
147: return encryptedString.substring(0, 2);
148: } catch (Exception e) {
149: return null;
150: }
151: }
152:
153: /**
154: * DES Encryption of a string using a salt.
155: *
156: * @param password the password to encrypt
157: * @param salt the salt to encrypt with
158: *
159: * @return the encrypted string (null if the salt is null).
160: */
161: private static String cryptDES(final String password,
162: final String salt) {
163: if (salt == null) {
164: return null;
165: }
166: return jcrypt.crypt(salt, password);
167: }
168:
169: /**
170: * DES comparison.
171: *
172: * @param password a clear password.
173: * @param encryptedPassword an already encrypted password.
174: *
175: * @return true if password matches, false otherwise.
176: */
177: private static boolean matchDES(final String password,
178: final String encryptedPassword) {
179: return encryptedPassword.equals(cryptDES(password,
180: getDESSalt(encryptedPassword)));
181: }
182:
183: }
|