2008年11月19日 星期三

Java 以 DES 加密,C# 解密

工作上,別的系統以java 實作,但我們的系統仍以 dotnet 實作。問題來了,需要加解密。試了幾次,答案如下。

import javax.crypto.*;
import javax.crypto.spec.*;

public class TestMain {
public static void main(String[] args) throws Exception
{
byte[] rgbIV = {(byte)11, (byte)12,(byte)13,(byte)14,
(byte)15,(byte)16,(byte)17,(byte)18};

byte[] rgbKey = {(byte)21, (byte)22,(byte)23,(byte)24,
(byte)25,(byte)26,(byte)27,(byte)28};

byte[] encrypedBytes = desEncrypt("AB123456", rgbKey, rgbIV );
String encrypedString = new sun.misc.BASE64Encoder().encode(encrypedBytes);
System.out.println(encrypedString);
}


public static byte[] desEncrypt(String message, byte[] rgbKey, byte[] rgbIV) throws Exception {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(rgbKey);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(rgbIV);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
return cipher.doFinal(message.getBytes("UTF-8"));
}
}

加密後的字串為 uv0cplrvtQ9KnRXKKd+MuQ==


使用 c# 來解密。當然需要使用同一把key



using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace ConsoleApplication13
{
class Program
{
static void Main(string[] args)
{
byte[] rgbIV = {(byte)11, (byte)12,(byte)13,(byte)14,
(byte)15,(byte)16,(byte)17,(byte)18};

byte[] rgbKey = {(byte)21, (byte)22,(byte)23,(byte)24,
(byte)25,(byte)26,(byte)27,(byte)28};

string reslut = DecryptString("uv0cplrvtQ9KnRXKKd+MuQ==", rgbIV, rgbKey);
Console.WriteLine(reslut);
}


///
/// DES解密字符串
///

/// 待解密的字符串
/// 解密密鑰,要求為8位,和加密密鑰相同
/// 解密成功返回解密後的字符串
public static string DecryptString(string cipherText, byte[] rgbIV, byte[] rgbKey)
{
byte[] inputByteArray = Convert.FromBase64String(cipherText);
DESCryptoServiceProvider dcsp = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, dcsp.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
return Encoding.UTF8.GetString(mStream.ToArray());
}
}
}

最近這裡寫的比我更詳細,請參考

2 則留言:

匿名 提到...

你好.我是個正在學習撰寫JAVA程式的新手.拜讀過您的網誌發現許多值得我學習的地方.尤其對DES的加解密特別有興趣.可是我想以JAVA寫出一個與您的程式可以相對應解密的程式卻屢屢失敗.不知是否可請教您如何實踐.可以請您有空的話指點一下嗎?麻煩您了.

秉程 提到...

按照文件了的程式應該可以 work了吧。
重點在於 dotnet 的 DES,等同於java 的 DES/CBC/PKCS5Padding 模式。

我對 java 並不熟。此篇文章是針對 java 與 dotnet 的交互加解密而說明的。如果您只想要了解 java 上如何實作 DES 的加解密,建議您尋找別的 solution.

Share with Facebook