最近在跟三方对接 对方采用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 }