梦想博客

C#与java aes加解密

calendar 2023/04/18
refresh-cw 2023/04/18
1523字,4分钟

最近在跟三方对接 对方采用AES加解密 作为一个资深neter Ctrl CV 是我最大的优点 所以我义正言辞的问他们要了demo 🔗
java demo代码: 🔗
 1public class EncryptDecryptTool
 2{
 3	private static final String defaultCharset = "UTF-8";
 4	private static final String KEY_AES = "AES";
 5	private static final String KEY_MD5 = "MD5";
 6	private static MessageDigest md5Digest;
 7
 8	static {
 9		try {
10			md5Digest = MessageDigest.getInstance(KEY_MD5);
11		} catch (NoSuchAlgorithmException e) {
12			//
13		}
14	}
15
16
17public String encrypt(String message, String key) throws Exception
18{
19	return doAES(message, key, Cipher.ENCRYPT_MODE);
20}
21
22
23public String decrypt(String message, String key) throws Exception
24{
25		return doAES(message, key, Cipher.DECRYPT_MODE);
26}
27    
28/**
29 * 加解密
30 *
31 * @param data
32 * @param key
33 * @param mode
34 * @return
35 * @throws NoSuchPaddingException 
36 * @throws NoSuchAlgorithmException 
37 */
38private static String doAES(String data, String key, int mode) throws Exception
39{
40 
41			if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) {
42		return null;
43	}
44	boolean encrypt = mode == Cipher.ENCRYPT_MODE;
45			byte[]
46	content;
47			if (encrypt) {
48		content = data.getBytes(defaultCharset);
49	} else {
50		content = Base64.decodeBase64(data.getBytes());
51	}
52	SecretKeySpec keySpec = new SecretKeySpec(md5Digest.digest(key.getBytes(defaultCharset)), KEY_AES);
53			Cipher cipher = Cipher.getInstance(KEY_AES);// 创建密码器
54cipher.init(mode, keySpec);// 初始化
55			byte[] result = cipher.doFinal(content);
56			if (encrypt) {
57				return new String(Base64.encodeBase64(result, false), defaultCharset);
58			} else {
59				return new String(result, defaultCharset);
60			}
61	   
62	}
63}
64
65   EncryptDecryptTool tool = new EncryptDecryptTool();
66	try
67	{
68	  //这里key的位数是个坑   之前找的一堆资料   java C#通用版啥的   都说key一定要是16位的   结果后来我发现 靠
69		String msg = tool.decrypt("{\"Name\":\"20180122T155221\",\"OrderNo\":\"Test1000012059021180000008153\"}", "64个英文字母");
70		System.out.println(msg);
71	}
72	catch (Exception e)
73	{
74		// TODO Auto-generated catch block
75		e.printStackTrace();
76	}
哇咔咔 这不是大名鼎鼎的java嘛 但这难不倒我 不是还有IKVM 照样Ctrl CV 🔗
新建一个.NET Standard项目NuGet 安装IKVM 🔗
C#主要代码 🔗
 1public class EncryptDecryptTool
 2{
 3	private static readonly string KEY_AES = "AES";
 4	private static readonly string KEY_MD5 = "MD5";
 5	private static MessageDigest md5Digest;
 6
 7	static EncryptDecryptTool()
 8	{
 9		try
10		{
11			md5Digest = MessageDigest.getInstance(KEY_MD5);
12		}
13		catch (NoSuchAlgorithmException e)
14		{
15			//
16		}
17	}
18
19	public string encrypt(string message, string key)
20	{
21		return doAES(message, key, Cipher.ENCRYPT_MODE);
22	}
23
24	public string decrypt(string message, string key)
25	{
26		return doAES(message, key, Cipher.DECRYPT_MODE);
27	}
28
29	/// <summary>
30	/// 
31	/// </summary>
32	/// <param name="data"></param>
33	/// <param name="key"></param>
34	/// <param name="mode"></param>
35	/// <returns></returns>
36	private static string doAES(string data, string key, int mode)
37	{
38
39
40		bool encrypt = mode == Cipher.ENCRYPT_MODE;
41		byte[] content;
42		if (encrypt)
43		{
44			content = Encoding.UTF8.GetBytes(data);
45		}
46		else
47		{
48			content = Convert.FromBase64String(data);
49		}
50		SecretKeySpec keySpec = new SecretKeySpec(md5Digest.digest(Encoding.UTF8.GetBytes(key)), KEY_AES);
51		Cipher cipher = Cipher.getInstance(KEY_AES);// 创建密码器
52		cipher.init(mode, keySpec);// 初始化
53		byte[] result = cipher.doFinal(content);
54		if (encrypt)
55		{
56			return Convert.ToBase64String(result);
57		}
58		else
59		{
60			return Encoding.UTF8.GetString(result);
61		}
62
63	}
64   
65}
66static void Main(string[] args)
67	{
68		var encryptDecryptTool = new EncryptDecryptTool();
69		Console.WriteLine(encryptDecryptTool.encrypt("jack","64位密钥"));
70	}
运行NetCore控制台 🔗
这是Net Framework Net Core以及IKVM不得不说的故事了 但是下午就要联调了 总不能给三方讲一千零一夜 没事这难不倒我 新建一个Net Framework控制台 🔗
 1static void Main(string[] args)
 2{
 3	try
 4	{
 5		var argsLength = args.Length;
 6		if (argsLength > 1)
 7		{
 8			EncryptDecryptTool tool = new EncryptDecryptTool();
 9			string result = string.Empty;
10			if (args[0] == "encrypt")
11			{
12				result = tool.encrypt(args[1]);
13			}
14			else
15			{
16				result = tool.decrypt(args[1]);
17			}
18			Console.WriteLine(result);
19		}
20
21	}
22	catch (Exception ex)
23	{
24		Console.WriteLine(ex.Message);
25	}
26
27}
Net Core调用 🔗
 1	string path = @"D:\WebSite\AESTool.exe";
 2	var method="encrypt";
 3	var msg="this is msg";
 4	string fileName = path;
 5	Process p = new Process();
 6	p.StartInfo.UseShellExecute = false;
 7	p.StartInfo.RedirectStandardOutput = true;
 8	p.StartInfo.FileName = fileName;
 9	p.StartInfo.CreateNoWindow = true;
10	p.StartInfo.Arguments = $"{method} {msg}";//参数以空格分隔
11	p.Start();
12	var output = await p.StandardOutput.ReadToEndAsync();
测试ok 没问题 就是时间有点久 加密解密每次差不多都要一秒 🔗


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


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


好吧 我知道你也没看懂


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


之前查了一堆资料 都说java C# AES加解密通用版 key的位都必须是16位 害的笨菜鸟陷入了思维误区 我们再看上面那段代码 Debug进去看 发现是用MD5算法根据key生成长度16的byte数据 16啊 多么敏感的数字 就是哈希计算 靠 🔗
果断google,Ctrl CV 🔗
 1public static class EncryptDecryptTool
 2{
 3
 4	private const string key = "qCOHfwhXgsZFBFSeZeGOlXtZbKOzApLBuZoWxrQjcmoxYHfrWZzdyFbvGuMcZqmC";
 5
 6	/// <summary>
 7	/// MD5哈希计算
 8	/// </summary>
 9	/// <param name="key"></param>
10	/// <returns></returns>
11	public static byte[] ConvertStringToMD5(string key)
12	{
13
14		byte[] ByteData = Encoding.UTF8.GetBytes(key);
15		MD5 oMd5 = MD5.Create();       
16		byte[] HashData = oMd5.ComputeHash(ByteData);
17		return HashData;
18	}
19
20
21	/// <summary>
22	/// AES加密 
23	/// </summary>
24	/// <param name="toEncrypt"></param>
25	/// <returns></returns>
26	public static string Encrypt(string toEncrypt)
27	{
28		byte[] keyArray = ConvertStringToMD5(key);
29		byte[] toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt);
30
31		RijndaelManaged rDel = new RijndaelManaged();
32		rDel.Key = keyArray;
33		rDel.Mode = CipherMode.ECB;
34		rDel.Padding = PaddingMode.PKCS7;
35
36		ICryptoTransform cTransform = rDel.CreateEncryptor();
37		byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
38
39		return Convert.ToBase64String(resultArray, 0, resultArray.Length);
40	}
41
42	/// <summary>
43	/// AES解密
44	/// </summary>
45	/// <param name="toDecrypt"></param>
46	/// <returns></returns>
47	public static string Decrypt(string toDecrypt)
48	{
49		byte[] keyArray = ConvertStringToMD5(key);
50		byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
51
52		RijndaelManaged rDel = new RijndaelManaged();
53		rDel.Key = keyArray;
54		rDel.Mode = CipherMode.ECB;
55		rDel.Padding = PaddingMode.PKCS7;
56
57		ICryptoTransform cTransform = rDel.CreateDecryptor();
58		byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
59
60		return Encoding.UTF8.GetString(resultArray);
61	}

参考资料 🔗

分类