Unix crypt(3) 是基於 DES 的單向雜湊函數,常用於密碼儲存。本文提供純 Java 移植版 JCrypt 類,完整實現標準演算法,包含鹽值處理、金鑰排程、S-Box 置換、最終編碼為 13 字元可列印字串。
Eswap0, Eswap1 (查表 con_salt)D_ENCRYPT)con_salt[64]:鹽值字元到 E-box 交換位模式的映射表shifts2[16]:每輪金鑰左移位數 (1 或 2 位)skb[8][64]:S-Box 壓縮置換表 (8 個 S-Box,各 64 入口)SPtrans[8][64]:S-Box 輸出經 P-Box 置換後的預計算表cov_2char[64]:6 位值到輸出字元集 (./0-9A-Za-z) 的映射package secure_election_system;
public class JCrypt {
private JCrypt() {}
private static final int ITERATIONS = 16;
private static final int con_salt[] = { /* 64 入口表 */ };
private static final boolean shifts2[] = { /* 16 輪移位旗標 */ };
private static final int skb[][] = { /* 8 S-Box 表 */ };
private static final int SPtrans[][] = { /* 8 SP 轉換表 */ };
private static final int cov_2char[] = { /* 64 字元編碼表 */ };
private static final int byteToUnsigned(byte b) { ... }
private static int fourBytesToInt(byte b[], int offset) { ... }
private static final void intToFourBytes(int iValue, byte b[], int offset) { ... }
private static final void PERM_OP(int a, int b, int n, int m, int results[]) { ... }
private static final int HPERM_OP(int a, int n, int m) { ... }
private static int[] des_set_key(byte key[]) { ... }
private static final int D_ENCRYPT(int L, int R, int S, int E0, int E1, int s[]) { ... }
private static final int[] body(int schedule[], int Eswap0, int Eswap1) { ... }
public synchronized static final String crypt(String salt, String original) {
while (salt.length() < 2) salt += "A";
StringBuffer buffer = new StringBuffer(" ");
buffer.setCharAt(0, salt.charAt(0));
buffer.setCharAt(1, salt.charAt(1));
int Eswap0 = con_salt[(int) salt.charAt(0)];
int Eswap1 = con_salt[(int) salt.charAt(1)] << 4;
byte key[] = new byte[8];
for (int i = 0; i < key.length && i < original.length(); i++) {
key[i] = (byte) (original.charAt(i) << 1);
}
int schedule[] = des_set_key(key);
int out[] = body(schedule, Eswap0, Eswap1);
byte b[] = new byte[9];
intToFourBytes(out[0], b, 0);
intToFourBytes(out[1], b, 4);
b[8] = 0;
for (int i = 2, y = 0, u = 0x80; i < 13; i++) {
for (int j = 0, c = 0; j < 6; j++) {
c <<= 1;
if (((int) b[y] & u) != 0) c |= 1;
u >>>= 1;
if (u == 0) { y++; u = 0x80; }
buffer.setCharAt(i, (char) cov_2char[c]);
}
}
return buffer.toString();
}
}
String hashed = JCrypt.crypt("ab", "myPassword"); // 產生 13 字元雜湊
// 驗證時重新計算並比對
if (JCrypt.crypt(hashed.substring(0,2), inputPassword).equals(hashed)) {
// 密碼正確
}
| 演算法 | 特點 | Java 實作 |
|---|---|---|
| BCrypt | Blowfish 基礎、內建鹽值、可調成本因子 | BCrypt.hashpw() (jBCrypt) |
| PBKDF2 | NIST 標準、HMAC 迭代、廣泛支援 | SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256") |
| Argon2 | 記憶體硬化、抗 GPU/ASIC、PHC 首獎 | Argon2Factory.create() (argon2-jvm) |