梦想博客

C#与java aes加解密

· 1329 words · 3 minutes to read

该文章来自csdn!

最近在跟三方对接 对方采用AES加解密 作为一个资深neter Ctrl CV 是我最大的优点 所以我义正言辞的问他们要了demo 🔗
java demo代码: 🔗
public class EncryptDecryptTool
{
	private static final String defaultCharset = "UTF-8";
	private static final String KEY_AES = "AES";
	private static final String KEY_MD5 = "MD5";
	private static MessageDigest md5Digest;

	static {
		try {
			md5Digest = MessageDigest.getInstance(KEY_MD5);
		} catch (NoSuchAlgorithmException e) {
			//
		}
	}


public String encrypt(String message, String key) throws Exception
{
	return doAES(message, key, Cipher.ENCRYPT_MODE);
}


public String decrypt(String message, String key) throws Exception
{
		return doAES(message, key, Cipher.DECRYPT_MODE);
}
    
/**
 * 加解密
 *
 * @param data
 * @param key
 * @param mode
 * @return
 * @throws NoSuchPaddingException 
 * @throws NoSuchAlgorithmException 
 */
private static String doAES(String data, String key, int mode) throws Exception
{
 
			if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) {
		return null;
	}
	boolean encrypt = mode == Cipher.ENCRYPT_MODE;
			byte[]
	content;
			if (encrypt) {
		content = data.getBytes(defaultCharset);
	} else {
		content = Base64.decodeBase64(data.getBytes());
	}
	SecretKeySpec keySpec = new SecretKeySpec(md5Digest.digest(key.getBytes(defaultCharset)), KEY_AES);
			Cipher cipher = Cipher.getInstance(KEY_AES);// 创建密码器
cipher.init(mode, keySpec);// 初始化
			byte[] result = cipher.doFinal(content);
			if (encrypt) {
				return new String(Base64.encodeBase64(result, false), defaultCharset);
			} else {
				return new String(result, defaultCharset);
			}
	   
	}
}

   EncryptDecryptTool tool = new EncryptDecryptTool();
	try
	{
	  //这里key的位数是个坑   之前找的一堆资料   java C#通用版啥的   都说key一定要是16位的   结果后来我发现 靠
		String msg = tool.decrypt("{\"Name\":\"20180122T155221\",\"OrderNo\":\"Test1000012059021180000008153\"}", "64个英文字母");
		System.out.println(msg);
	}
	catch (Exception e)
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
哇咔咔 这不是大名鼎鼎的java嘛 但这难不倒我 不是还有IKVM 照样Ctrl CV 🔗
新建一个.NET Standard项目NuGet 安装IKVM 🔗
C#主要代码 🔗
public class EncryptDecryptTool
{
	private static readonly string KEY_AES = "AES";
	private static readonly string KEY_MD5 = "MD5";
	private static MessageDigest md5Digest;

	static EncryptDecryptTool()
	{
		try
		{
			md5Digest = MessageDigest.getInstance(KEY_MD5);
		}
		catch (NoSuchAlgorithmException e)
		{
			//
		}
	}

	public string encrypt(string message, string key)
	{
		return doAES(message, key, Cipher.ENCRYPT_MODE);
	}

	public string decrypt(string message, string key)
	{
		return doAES(message, key, Cipher.DECRYPT_MODE);
	}

	/// <summary>
	/// 
	/// </summary>
	/// <param name="data"></param>
	/// <param name="key"></param>
	/// <param name="mode"></param>
	/// <returns></returns>
	private static string doAES(string data, string key, int mode)
	{


		bool encrypt = mode == Cipher.ENCRYPT_MODE;
		byte[] content;
		if (encrypt)
		{
			content = Encoding.UTF8.GetBytes(data);
		}
		else
		{
			content = Convert.FromBase64String(data);
		}
		SecretKeySpec keySpec = new SecretKeySpec(md5Digest.digest(Encoding.UTF8.GetBytes(key)), KEY_AES);
		Cipher cipher = Cipher.getInstance(KEY_AES);// 创建密码器
		cipher.init(mode, keySpec);// 初始化
		byte[] result = cipher.doFinal(content);
		if (encrypt)
		{
			return Convert.ToBase64String(result);
		}
		else
		{
			return Encoding.UTF8.GetString(result);
		}

	}
   
}
static void Main(string[] args)
	{
		var encryptDecryptTool = new EncryptDecryptTool();
		Console.WriteLine(encryptDecryptTool.encrypt("jack","64位密钥"));
	}
运行NetCore控制台 🔗
这是Net Framework Net Core以及IKVM不得不说的故事了 但是下午就要联调了 总不能给三方讲一千零一夜 没事这难不倒我 新建一个Net Framework控制台 🔗
static void Main(string[] args)
{
	try
	{
		var argsLength = args.Length;
		if (argsLength > 1)
		{
			EncryptDecryptTool tool = new EncryptDecryptTool();
			string result = string.Empty;
			if (args[0] == "encrypt")
			{
				result = tool.encrypt(args[1]);
			}
			else
			{
				result = tool.decrypt(args[1]);
			}
			Console.WriteLine(result);
		}

	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.Message);
	}

}
Net Core调用 🔗
	string path = @"D:\WebSite\AESTool.exe";
	var method="encrypt";
	var msg="this is msg";
	string fileName = path;
	Process p = new Process();
	p.StartInfo.UseShellExecute = false;
	p.StartInfo.RedirectStandardOutput = true;
	p.StartInfo.FileName = fileName;
	p.StartInfo.CreateNoWindow = true;
	p.StartInfo.Arguments = $"{method} {msg}";//参数以空格分隔
	p.Start();
	var output = await p.StandardOutput.ReadToEndAsync();
测试ok 没问题 就是时间有点久 加密解密每次差不多都要一秒 🔗


就这样跑了一段时间 今天闲下来 想起上次的一秒


嗯 写好辞职申请 备份 好的 我要开始重构了 嗯 知己知彼百战不殆 那我们先去维密上大概了解一下AES 🔗


好吧 我知道你也没看懂


我们还是看代码吧 作为一个资深程序员的直觉 🔗


之前查了一堆资料 都说java C# AES加解密通用版 key的位都必须是16位 害的笨菜鸟陷入了思维误区 我们再看上面那段代码 Debug进去看 发现是用MD5算法根据key生成长度16的byte数据 16啊 多么敏感的数字 就是哈希计算 靠 🔗
果断google,Ctrl CV 🔗
public static class EncryptDecryptTool
{

	private const string key = "qCOHfwhXgsZFBFSeZeGOlXtZbKOzApLBuZoWxrQjcmoxYHfrWZzdyFbvGuMcZqmC";

	/// <summary>
	/// MD5哈希计算
	/// </summary>
	/// <param name="key"></param>
	/// <returns></returns>
	public static byte[] ConvertStringToMD5(string key)
	{

		byte[] ByteData = Encoding.UTF8.GetBytes(key);
		MD5 oMd5 = MD5.Create();       
		byte[] HashData = oMd5.ComputeHash(ByteData);
		return HashData;
	}


	/// <summary>
	/// AES加密 
	/// </summary>
	/// <param name="toEncrypt"></param>
	/// <returns></returns>
	public static string Encrypt(string toEncrypt)
	{
		byte[] keyArray = ConvertStringToMD5(key);
		byte[] toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt);

		RijndaelManaged rDel = new RijndaelManaged();
		rDel.Key = keyArray;
		rDel.Mode = CipherMode.ECB;
		rDel.Padding = PaddingMode.PKCS7;

		ICryptoTransform cTransform = rDel.CreateEncryptor();
		byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

		return Convert.ToBase64String(resultArray, 0, resultArray.Length);
	}

	/// <summary>
	/// AES解密
	/// </summary>
	/// <param name="toDecrypt"></param>
	/// <returns></returns>
	public static string Decrypt(string toDecrypt)
	{
		byte[] keyArray = ConvertStringToMD5(key);
		byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);

		RijndaelManaged rDel = new RijndaelManaged();
		rDel.Key = keyArray;
		rDel.Mode = CipherMode.ECB;
		rDel.Padding = PaddingMode.PKCS7;

		ICryptoTransform cTransform = rDel.CreateDecryptor();
		byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

		return Encoding.UTF8.GetString(resultArray);
	}

参考资料 🔗

Categories