最近需要使用C#的DES解密工具類解密字符串,但是要解密的字符串是使用java進行DES加密的,去網上查了關於C#和java關於DES加密解密的資料,發現可以相互加密解密的時候,java進行DES加密一般都會寫成如下:
public static byte[] encrypt(String message, String key) throws Exception {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 密鑰
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
// 偏移量
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
return cipher.doFinal(message.getBytes("UTF-8"));
}
因為初始化Cipher的時候設置了密鑰和偏移量,所以C#的DESCryptoServiceProvider類可以很容易的進行解密。C#解密代碼如下:
public static string Decode(string str, string key)
{
try
{
DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
// 密鑰
provider.Key = Encoding.ASCII.GetBytes(key.Substring(0, 8));
// 偏移量
provider.IV = Encoding.ASCII.GetBytes(key.Substring(0, 8));
byte[] buffer = new byte[str.Length / 2];
for (int i = 0; i < (str.Length / 2); i++)
{
int num2 = Convert.ToInt32(str.Substring(i * 2, 2), 0x10);
buffer[i] = (byte)num2;
}
MemoryStream stream = new MemoryStream();
CryptoStream stream2 = new CryptoStream(stream, provider.CreateDecryptor(),CryptoStreamMode.Write);
stream2.Write(buffer, 0, buffer.Length);
stream2.FlushFinalBlock();
stream.Close();
return Encoding.GetEncoding("GB2312").GetString(stream.ToArray());
}
catch (Exception) { return ""; }
}
現在的問題是java的DES加密不僅僅有上面一種寫法,我需要解密的字符串是使用如下java代碼進行加密的:
public static byte[] encrypt(String message, String key) throws Exception {
SecureRandom sr = new SecureRandom();
Cipher cipher = Cipher.getInstance("DES");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
// 這裡使用的是另一個init方法
cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);
return cipher.doFinal(message.getBytes("UTF-8"));
}
這樣的話,java加密的偏移量沒有設置,而且通過測試發現就算上面設置了偏移量,Cipher cipher = Cipher.getInstance("DES");和Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); 加密之後的結果也不一樣,
所以這樣的話使用C#解密的時候就不知道相應的偏移量應該怎麼設置,麻煩各位高手指導一下,謝謝
問題補充:
DES加密解密結果一般要注意的地方:密鑰、偏移量、塊密碼模式、填充模式
java DES加密的時候:
如果使用這種方式,Cipher cipher = Cipher.getInstance("DES"); 此時塊密碼模式用ECB模式,C#DES類默認模式是CBC模式,所以如果java使用上面的方式進行初始化的時候,使用C#解密的時候要記得設置Mode屬性為ECB,另外,如果沒有設置偏移量,C#解密的時候Key和IV設置成一樣的就可以進行正常解密了。
所以對於上面java的第2種DES加密方法,使用C#解密的時候只需要在解密之前加上
provider.Mode = CipherMode.ECB;
就可以了