參考:http://blog.csdn.net/cparent/article/details/40652051
DES加密算法作為一個過時的東西,使用的項目已經很少了。最近在調試與服務器端進行DES加密通訊時,加解密老是錯誤,而且使用的是最為簡單的ECB模式。
服務器端使用的JAVA JDK自帶的DES加密算法。
后通過查找資料發現,其設置密鑰的方式並不簡單,主要有兩點需要注意:
1. DES_string_to_key,該方法並不是將字符串直接設置為密鑰,而是根據該字符串,生成一組經過計算的Key。一起來看一下代碼:
void DES_string_to_key(const char *str, DES_cblock *key) { DES_key_schedule ks; int i, length; register unsigned char j; memset(key, 0, 8); //密鑰的長度為8位 length = strlen(str); #ifdef OLD_STR_TO_KEY //這部分是過時的轉換方式,已經不適用 for (i = 0; i < length; i++) (*key)[i % 8] ^= (str[i] << 1); #else /* MIT COMPATIBLE */ for (i = 0; i < length; i++) { j = str[i]; if ((i % 16) < 8) //對於前8位,將每個字符左移一位,再與0進行異或 (*key)[i % 8] ^= (j << 1); else { //對於后續的密鑰字符,進行如下操作,其實為一個逆排序,假設原數據為 76543210B /* Reverse the bit order 05/05/92 eay */ j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f);//高4位與低4位進行交換 32107654B j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33);//左移2位,取6、7,2、3位,右移2位,取4、5,0,1位 10325476B j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55);//左移1位,取5、7,1、3位,右移1位,取4、6,0、2位 01234567B (*key)[7 - (i % 8)] ^= j; } } #endif DES_set_odd_parity(key); #ifdef EXPERIMENTAL_STR_TO_STRONG_KEY if (DES_is_weak_key(key)) (*key)[7] ^= 0xF0; DES_set_key(key, &ks); #else DES_set_key_unchecked(key, &ks); #endif DES_cbc_cksum((const unsigned char *)str, key, length, &ks, key); OPENSSL_cleanse(&ks, sizeof(ks)); DES_set_odd_parity(key); }
2. 不能使用DES_set_key_checked,而要使用DES_set_key_unchecked。因為使用前者,它會檢查密鑰的奇偶性和密鑰的強度。經常會導致密鑰無法通過檢驗,而無法成功設置。
/*- * return 0 if key parity is odd (correct), * return -1 if key parity error, * return -2 if illegal weak key. */ int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule) { if (!DES_check_key_parity(key)) return (-1); if (DES_is_weak_key(key)) return (-2); DES_set_key_unchecked(key, schedule); return 0; }