首页 > 技术文章 > AES加密

zhao-gang 2017-12-03 19:30 原文

         在开发过程中遇到了使用AES加密的地方,需要使用C#方法加密,java方法解密,涉及到AES加密和RSA加密,本文先做一下AES加密笔录。

 

         AES加密算法即密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法。AES已经变成目前对称加密中最流行算法之一;AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据。

         AES有五种加密模式:CBC, CFB, ECB,OFB,PCBC;有三种填充模式:NoPadding,PKCS5Padding,ISO10126Padding。从网上查到已经有人总结了一些AES加密模式和填充方式,如下:

         算法/模式/填充          16字节加密后数据长度       不满16字节加密后长度

   AES/CBC/NoPadding             16               不支持

   AES/CBC/PKCS5Padding           32                16

   AES/CBC/ISO10126Padding          32                16               

   AES/CFB/NoPadding             16              原始数据长度

   AES/CFB/PKCS5Padding           32                16

   AES/CFB/ISO10126Padding           32                16

   AES/ECB/NoPadding            16                    不支持

   AES/ECB/PKCS5Padding           32                16

   AES/ECB/ISO10126Padding         32                16

   AES/OFB/NoPadding            16              原始数据长度

   AES/OFB/PKCS5Padding           32                16

   AES/OFB/ISO10126Padding         32                16

   AES/PCBC/NoPadding            16               不支持

   AES/PCBC/PKCS5Padding          32                16

   AES/PCBC/ISO10126Padding         32                16

 

        不带模式和填充来获取AES算法的时候,其默认使用ECB/PKCS5Padding。

        我使用的是默认的ECB模式,PKCS5Padding填充,使用base64转码。

        Java和C#加密解密是互通的,能相互加密解密,统一采用UTF-8编码

        模式:Java的ECB模式对应C#的System.Security.Cryptography.CipherMode.ECB

        填充方法:Java的PKCS5Padding对应C#的System.Security.Cryptography.PaddingMode.PKCS7

        Java代码如下:

 1 package cn.wutian.util;
 2 
 3 import java.security.NoSuchAlgorithmException;
 4 import java.security.SecureRandom;
 5 
 6 import javax.crypto.*;
 7 import javax.crypto.spec.SecretKeySpec;
 8 
 9 import sun.misc.*;
10 
11 @SuppressWarnings("restriction")
12 public class EncryptUtil {
13 
14     public static String aesEncrypt(String str, String key) throws Exception {
15         if (str == null || key == null) return null;
16         Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
17         cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
18         byte[] bytes = cipher.doFinal(str.getBytes("utf-8"));
19         return new BASE64Encoder().encode(bytes);
20     }
21 
22     public static String aesDecrypt(String str, String key) throws Exception {
23         if (str == null || key == null) return null;
24         Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
25         cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
26         byte[] bytes = new BASE64Decoder().decodeBuffer(str);
27         bytes = cipher.doFinal(bytes);
28         return new String(bytes, "utf-8");
29     }
30 }

       C#代码如下:

 

 1 using System;
 2 using System.Security.Cryptography;
 3 using System.Text;
 4 
 5 namespace CSharp.Util.Security
 6 {
 7    
 8         /// <summary>
 9         ///  AES 加密
10         /// </summary>
11         /// <param name="str"></param>
12         /// <param name="key"></param>
13         /// <returns></returns>
14         public static string AesEncrypt(string str, string key)
15         {
16             if (string.IsNullOrEmpty(str)) return null;
17             Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);
18 
19             System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged
20             {
21                 Key = Encoding.UTF8.GetBytes(key),
22                 Mode = System.Security.Cryptography.CipherMode.ECB,
23                 Padding = System.Security.Cryptography.PaddingMode.PKCS7
24             };
25 
26             System.Security.Cryptography.ICryptoTransform cTransform = rm.CreateEncryptor();
27             Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
28 
29             return Convert.ToBase64String(resultArray, 0, resultArray.Length);
30         }
31 
32         /// <summary>
33         ///  AES 解密
34         /// </summary>
35         /// <param name="str"></param>
36         /// <param name="key"></param>
37         /// <returns></returns>
38         public static string AesDecrypt(string str, string key)
39         {
40             if (string.IsNullOrEmpty(str)) return null;
41             Byte[] toEncryptArray = Convert.FromBase64String(str);
42 
43             System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged
44             {
45                 Key = Encoding.UTF8.GetBytes(key),
46                 Mode = System.Security.Cryptography.CipherMode.ECB,
47                 Padding = System.Security.Cryptography.PaddingMode.PKCS7
48             };
49 
50             System.Security.Cryptography.ICryptoTransform cTransform = rm.CreateDecryptor();
51             Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
52 
53             return Encoding.UTF8.GetString(resultArray);
54         }
55     }
56 }

       我这里的key值是由str经过MD5加密得到。

       Java代码如下:

1   public static String EncoderByMd5(String str)
2     throws Exception
3   {
4     MessageDigest md5 = MessageDigest.getInstance("MD5");
5     String newstr = new BASE64Encoder().encode(md5.digest(str.getBytes("UTF-8")));
6     return newstr;
7   }

        C#代码如下:

1 public static string EncoderByMd5(string str)
2         {
3             MD5 md5 = new MD5CryptoServiceProvider();
4             var byteText = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
5             return Convert.ToBase64String(byteText);
6         }

 

   

      

 

推荐阅读