码迷,mamicode.com
首页 > 编程语言 > 详细

记一次Java AES 加解密 对应C# AES加解密 的一波三折

时间:2018-11-15 13:48:57      阅读:329      评论:0      收藏:0      [点我收藏+]

标签:res   nsf   elm   private   har   only   throws   初始化   问题   

最近在跟三方对接 对方采用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);
        }
打完收工

技术分享图片

记一次Java AES 加解密 对应C# AES加解密 的一波三折

标签:res   nsf   elm   private   har   only   throws   初始化   问题   

原文地址:https://www.cnblogs.com/aishangyipiyema/p/9948011.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!