• AES Java加密 C#解密 (128-ECB加密模式)


    在项目中遇到这么一个问题:

    java端需要把一些数据AES加密后传给C#端,找了好多资料,算是解决了,分享一下:

    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import java.security.SecureRandom;
    
    public class AesEncodeUtil {
      
      private final static String transferKey ="qazwsxedcrfv12345";
    
      public static void main(String[] args) throws Exception {
    
    
        String a = aesTransferEncrypt("QAZwsx123!@#$%^&*");
        System.out.println(a);
        System.out.println(aesTransferDncrypt(a));
    
      }
    
      /**
       * 传输用加密
       * @param content
       * @return
       * @throws Exception
       */
      public static String aesTransferEncrypt(String content) throws Exception {
        return base64Encode(aesEncryptToBytes(content, transferKey));
      }
    
      /**
       * 传输用解密
       * @param content
       * @return
       * @throws Exception
       */
      public static String aesTransferDncrypt(String encryptStr) throws Exception {
        return aesDecryptByBytes(base64Decode(encryptStr), transferKey);
      }
    
      /**
       * base 64 encode
       * @param bytes 待编码的byte[]
       * @return 编码后的base 64 code
       */
      private static String base64Encode(byte[] bytes) {
        return new BASE64Encoder().encode(bytes);
      }
    
      /**
       * base 64 decode
       * @param base64Code 待解码的base 64 code
       * @return 解码后的byte[]
       * @throws Exception
       */
      private static byte[] base64Decode(String base64Code) throws Exception {
        return new BASE64Decoder().decodeBuffer(base64Code);
      }
    
      /**
       * AES加密
       * @param content 待加密的内容
       * @param encryptKey 加密密钥
       * @return 加密后的byte[]
       * @throws Exception
       */
      private static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
        secureRandom.setSeed(encryptKey.getBytes());
        kgen.init(128, secureRandom);
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, kgen.generateKey());
        return cipher.doFinal(content.getBytes("UTF-8"));
      }
    
      /**
       * AES解密
       * @param encryptBytes 待解密的byte[]
       * @param decryptKey 解密密钥
       * @return 解密后的String
       * @throws Exception
       */
      private static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
        secureRandom.setSeed(decryptKey.getBytes());
        kgen.init(128, secureRandom);
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE,kgen.generateKey());
        byte[] decryptBytes = cipher.doFinal(encryptBytes);
        return new String(decryptBytes,"UTF-8");
      }
    }

    java代码加密/解密运行结果:

    加密结果:BKscOr7eK4jTO5Hcw5oxqS8HWg2SRhtGfMctz8t/45g=
    解密结果:QAZwsx123!@#$%^&*

    再看看C#代码:

    /// <summary>
            /// AES加密 (128-ECB加密模式)
            /// </summary>
            /// <param name="toEncrypt">内容</param>
            /// <param name="key">秘钥</param>
            /// <returns></returns>
            public static string AESEncrypt(string toEncrypt, string key)
            {
                byte[] keyArray = Convert.FromBase64String(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解密(128-ECB加密模式)
            /// </summary>
            /// <param name="toDecrypt">密文</param>
            /// <param name="key">秘钥(Base64String)</param>
            /// <returns></returns>
            public static string AESDecrypt(string toDecrypt, string key)
            {
                try
                {
                    byte[] keyArray = Convert.FromBase64String(key); //128bit
                    byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
                    RijndaelManaged rDel = new RijndaelManaged();
                    rDel.Key = keyArray; //获取或设置对称算法的密钥
                    rDel.Mode = CipherMode.ECB; //获取或设置对称算法的运算模式,必须设置为ECB  
                    rDel.Padding = PaddingMode.PKCS7; //获取或设置对称算法中使用的填充模式,必须设置为PKCS7  
                    ICryptoTransform cTransform = rDel.CreateDecryptor(); //用当前的 Key 属性和初始化向量 (IV) 创建对称解密器对象
                    byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
                    return Encoding.UTF8.GetString(resultArray);
                }
                catch
                {
                    return null;
                }
            }

    但是如果直接把 transferKey ="qazwsxedcrfv12345" 和 加密结果:BKscOr7eK4jTO5Hcw5oxqS8HWg2SRhtGfMctz8t/45g=

    给C#,C#是无法解密的,因为 rDel.Key = keyArray; 会报错。

    那么怎么办呢? 其实我们要把transferKey ="qazwsxedcrfv12345" 处理下,

    import java.security.NoSuchAlgorithmException;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import sun.misc.BASE64Encoder;

    public class t1 {

    public static void main(String[] args) throws NoSuchAlgorithmException {
    String transferKey ="bt龘靐麷鸜郁nm018讟虋纞idnwtyaTN滟厵麷鸜郁骊NkkdTnd11_!@$齽齼鼺黸TTASdg212c驫饢籱21_djTdj";
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    java.security.SecureRandom random = java.security.SecureRandom.getInstance("SHA1PRNG");
    random.setSeed(transferKey.getBytes());
    kgen.init(128, random);
    SecretKey secretKey = kgen.generateKey();
    byte[] enCodeFormat = secretKey.getEncoded();
    BASE64Encoder coder = new BASE64Encoder();

    System.out.println(coder.encode(enCodeFormat));

    }

    }

    运行结果:0UkIZmHsXb0BUql/L3R6Aw== 才是C#需要的key

    看看C#调用及结果:

     以上只是一个简单的示例。

  • 相关阅读:
    elk 分布式数据同步
    mget 同时获取
    Jzoj1460 无题noname
    Jzoj1460 无题noname
    Jzoj1322硬币
    Jzoj1322硬币
    Jzoj1321 灯
    Jzoj1321 灯
    Jzoj1310 生日礼物
    Jzoj1310 生日礼物
  • 原文地址:https://www.cnblogs.com/zhangzhi19861216/p/5853472.html
Copyright © 2020-2023  润新知