OpenSSL 中DES-ECB 加密使用注意事項

參考: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位,取六、7,二、3位,右移2位,取四、5,0,1位 10325476B
			j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55);//左移1位,取五、7,一、3位,右移1位,取四、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;
}
相關文章
相關標籤/搜索