AES 加密,net和java 通用加密

本文介绍了一种Java与.NET项目间的加密交互方案,包括自定义异常处理、多种格式的编码解码工具类、AES加密类及其.NET对应的实现。涵盖了Hex/Base64编码、自定义base62编码、URL编码等,并提供了详细的AES加密解密过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目里面很多地方用到java和.net 项目交互加密,网上找了圈不尽人意,这里整理一下


一、java类


1.自定义异常类


package com.alvin.modules.utils.encrypt;

/**
 *  自定义加密解密时产生的异常类
 */
public class CryptException extends RuntimeException {

	private static final long serialVersionUID = 1L;

	public CryptException() {
	}

	public CryptException(String msg, Throwable e) {
		super(msg, e);
	}

	public CryptException(String msg) {
		super(msg);
	}

	public CryptException(Throwable cause) {
		super(cause);
	}
}

2.封装各种格式的编码解码工具类.


package com.alvin.modules.utils.encrypt;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

/**
 * 封装各种格式的编码解码工具类.
 * 
 * 1.Commons-Codec的 hex/base64 编码
 * 2.自定义的base62 编码
 * 3.Commons-Lang的xml/html escape
 * 4.JDK提供的URLEncoder
 * 
 */
public class Encodes {

	private static final String DEFAULT_URL_ENCODING = "UTF-8";
	private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();

	/**
	 * Hex编码.
	 */
	public static String encodeHex(byte[] input) {
		return Hex.encodeHexString(input);
	}

	/**
	 * Hex解码.
	 */
	public static byte[] decodeHex(String input) {
		try {
			return Hex.decodeHex(input.toCharArray());
		} catch (DecoderException e) {
			throw new CryptException("Hex解码出错:", e);
		}
	}

	/**
	 * Base64编码.
	 */
	public static String encodeBase64(byte[] input) {
		return Base64.encodeBase64String(input);
	}

	/**
	 * Base64编码, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548).
	 */
	public static String encodeUrlSafeBase64(byte[] input) {
		return Base64.encodeBase64URLSafeString(input);
	}

	/**
	 * Base64解码.
	 */
	public static byte[] decodeBase64(String input) {
		return Base64.decodeBase64(input);
	}

	/**
	 * Base62编码。
	 */
	public static String encodeBase62(byte[] input) {
		char[] chars = new char[input.length];
		for (int i = 0; i < input.length; i++) {
			chars[i] = BASE62[((input[i] & 0xFF) % BASE62.length)];
		}
		return new String(chars);
	}

	/**
	 * URL 编码, Encode默认为UTF-8. 
	 */
	public static String urlEncode(String part) {
		try {
			return URLEncoder.encode(part, DEFAULT_URL_ENCODING);
		} catch (UnsupportedEncodingException e) {
			throw new CryptException("URL 编码出错:", e);
		}
	}

	/**
	 * URL 解码, Encode默认为UTF-8. 
	 */
	public static String urlDecode(String part) {

		try {
			return URLDecoder.decode(part, DEFAULT_URL_ENCODING);
		} catch (UnsupportedEncodingException e) {
			throw new CryptException("URL 解码出错:", e);
		}
	}
}

3.AES加密类


package com.alvin.modules.utils.encrypt;

import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.log4j.Logger;



/**
 * 支持HMAC-SHA1消息签名 及 DES/AES对称加密的工具类.
 * 
 * 支持Hex与Base64两种编码方式.
 * 
 */
public class Cryptos {
	private static Logger logger = Logger.getLogger(Cryptos.class);
	/**
	 * 自定义密钥
	 */
	private String strDefaultKey = "0123456789012345";
	private byte[] key = strDefaultKey.getBytes();
	
	private static final String AES = "AES";
	private static final String AES_CBC = "AES/CBC/PKCS5Padding";
	private static final String HMACSHA1 = "HmacSHA1";

	private static final int DEFAULT_HMACSHA1_KEYSIZE = 160; //RFC2401
	private static final int DEFAULT_AES_KEYSIZE = 128;
	private static final int DEFAULT_IVSIZE = 16;

	private static SecureRandom random = new SecureRandom();
	
	public Cryptos(){
	}
	public Cryptos(String strDefaultKey){
		this.strDefaultKey = strDefaultKey;
		this.key = strDefaultKey.getBytes();
	}

	//-- HMAC-SHA1 funciton --//
	/**
	 * 使用HMAC-SHA1进行消息签名, 返回字节数组,长度为20字节.
	 * 
	 * @param input 原始输入字符数组
	 * @param key HMAC-SHA1密钥
	 */
	public static byte[] hmacSha1(byte[] input, byte[] key) {
		try {
			SecretKey secretKey = new SecretKeySpec(key, HMACSHA1);
			Mac mac = Mac.getInstance(HMACSHA1);
			mac.init(secretKey);
			return mac.doFinal(input);
		} catch (GeneralSecurityException e) {
			throw new CryptException("使用HMAC-SHA1进行消息签名出错:",e);
		}
	}

	/**
	 * 校验HMAC-SHA1签名是否正确.
	 * 
	 * @param expected 已存在的签名
	 * @param input 原始输入字符串
	 * @param key 密钥
	 */
	public static boolean isMacValid(byte[] expected, byte[] input, byte[] key) {
		byte[] actual = hmacSha1(input, key);
		return Arrays.equals(expected, actual);
	}

	/**
	 * 生成HMAC-SHA1密钥,返回字节数组,长度为160位(20字节).
	 * HMAC-SHA1算法对密钥无特殊要求, RFC2401建议最少长度为160位(20字节).
	 */
	public static byte[] generateHmacSha1Key() {
		try {
			KeyGenerator keyGenerator = KeyGenerator.getInstance(HMACSHA1);
			keyGenerator.init(DEFAULT_HMACSHA1_KEYSIZE);
			SecretKey secretKey = keyGenerator.generateKey();
			return secretKey.getEncoded();
		} catch (GeneralSecurityException e) {
			throw new CryptException("生成HMAC-SHA1密钥出错:",e);
		}
	}

	//-- AES funciton --//
	/**
	 * 使用AES加密原始字符串.
	 * 
	 * @param input 原始输入字符数组
	 * @param key 符合AES要求的密钥
	 */
	public byte[] aesEncrypt(byte[] input) {
		if (key.length != 16) {
			logger.info("Key长度不是16位");
		}
		
		return aes(input, key, Cipher.ENCRYPT_MODE);
	}
	
	/**
	 * 使用AES加密原始字符串.
	 * 
	 * @param input 原始输入字符串
	 */
	public String aesEncrypt(String input) {
		try{
			byte[] encryptResult = aesEncrypt(input.getBytes("utf-8"));
			return Encodes.encodeHex(encryptResult);
		} catch (Exception e) {
			throw new CryptException("生成HMAC-SHA1密钥出错:",e);
		}
	}

	/**
	 * 使用AES加密原始字符串.
	 * 
	 * @param input 原始输入字符数组
	 * @param key 符合AES要求的密钥
	 * @param iv 初始向量
	 */
	public static byte[] aesEncrypt(byte[] input, byte[] key, byte[] iv) {
		return aes(input, key, iv, Cipher.ENCRYPT_MODE);
	}

	/**
	 * 使用AES解密字符串, 返回原始字符串.
	 * 
	 * @param input Hex编码的加密字符串
	 * @param key 符合AES要求的密钥
	 * @throws UnsupportedEncodingException 
	 */
	public String aesDecrypt(byte[] input) throws UnsupportedEncodingException {
		if (key.length != 16) {
			logger.info("Key长度不是16位");
		}
		byte[] decryptResult = aes(input, key, Cipher.DECRYPT_MODE);
		//return new String(decryptResult);
		return new String(decryptResult,"utf-8");
	}
	
	/**
	 * 使用AES解密字符串, 返回原始字符串.
	 * 
	 * @param input Hex编码的加密字符串
	 * @throws UnsupportedEncodingException 
	 */
	public String aesDecrypt(String input) {
		try{
			return aesDecrypt(Encodes.decodeHex(input));
		} catch (Exception e) {
			throw new CryptException("解密出错:",e);
		}
	}

	/**
	 * 使用AES解密字符串, 返回原始字符串.
	 * 
	 * @param input Hex编码的加密字符串
	 * @param key 符合AES要求的密钥
	 * @param iv 初始向量
	 * @throws UnsupportedEncodingException 
	 */
	public static String aesDecrypt(byte[] input, byte[] key, byte[] iv) throws UnsupportedEncodingException {
		byte[] decryptResult = aes(input, key, iv, Cipher.DECRYPT_MODE);
		return new String(decryptResult,"utf-8");
	}

	/**
	 * 使用AES加密或解密无编码的原始字节数组, 返回无编码的字节数组结果.
	 * 
	 * @param input 原始字节数组
	 * @param key 符合AES要求的密钥
	 * @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE
	 */
	private static byte[] aes(byte[] input, byte[] key, int mode) {
		try {
			SecretKey secretKey = new SecretKeySpec(key, AES);
			Cipher cipher = Cipher.getInstance(AES);
			cipher.init(mode, secretKey);
			return cipher.doFinal(input);
		} catch (GeneralSecurityException e) {
			throw new CryptException("使用AES加密或解密无编码的原始字节数组出错:",e);
		}
	}

	/**
	 * 使用AES加密或解密无编码的原始字节数组, 返回无编码的字节数组结果.
	 * 
	 * @param input 原始字节数组
	 * @param key 符合AES要求的密钥
	 * @param iv 初始向量
	 * @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE
	 */
	private static byte[] aes(byte[] input, byte[] key, byte[] iv, int mode) {
		try {
			SecretKey secretKey = new SecretKeySpec(key, AES);
			IvParameterSpec ivSpec = new IvParameterSpec(iv);
			Cipher cipher = Cipher.getInstance(AES_CBC);
			cipher.init(mode, secretKey, ivSpec);
			return cipher.doFinal(input);
		} catch (GeneralSecurityException e) {
			throw new CryptException("使用AES加密或解密无编码的原始字节数组:",e);
		}
	}

	/**
	 * 生成AES密钥,返回字节数组, 默认长度为128位(16字节).
	 */
	public static byte[] generateAesKey() {
		return generateAesKey(DEFAULT_AES_KEYSIZE);
	}

	/**
	 * 生成AES密钥,可选长度为128,192,256位.
	 */
	public static byte[] generateAesKey(int keysize) {
		try {
			KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
			keyGenerator.init(keysize);
			SecretKey secretKey = keyGenerator.generateKey();
			return secretKey.getEncoded();
		} catch (GeneralSecurityException e) {
			throw new CryptException("生成AES密钥出错:",e);
		}
	}

	/**
	 * 生成随机向量,默认大小为cipher.getBlockSize(), 16字节.
	 */
	public static byte[] generateIV() {
		byte[] bytes = new byte[DEFAULT_IVSIZE];
		random.nextBytes(bytes);
		return bytes;
	}
	
	public byte[] getKey() {
		return key;
	}
	public void setKey(byte[] key) {
		this.key = key;
	}
}

二、c#代码


using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace alvin.aes
{
    public class AesUtils
    {
        public string myIV = "0123456789012345";

        public static Encoding encoding = UTF8Encoding.Default;

        /// <summary>
        /// 选择加密因子
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private string getIv(string key)
        {
            if (key == null || key.Trim() == "")
            {
                return myIV;
            }
            else
            {
                return key;
            }
        }


        #region aes加密
        /// <summary>
        /// AES加密
        /// </summary>
        /// <param name="toEncrypt">加密串</param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string Encrypt(string toEncrypt, string key)
        {
            byte[] resultArray = Encrypt_byte(toEncrypt, key);
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        /// <summary>
        /// AES加密
        /// </summary>
        /// <param name="toEncrypt">加密串</param>
        /// <param name="key"></param>
        /// <returns></returns>
        private byte[] Encrypt_byte(string toEncrypt, string key)
        {
            key = getIv(key);
            byte[] keyArray = encoding.GetBytes(key);
            byte[] toEncryptArray = encoding.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);
            return resultArray;
        }



        /// <summary>
        /// aes加密(转换成16位)
        /// </summary>
        /// <param name="toEncrypt">加密串</param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string Encrypt_16(string toEncrypt, string key)
        {
            byte[] resultArray = Encrypt_byte(toEncrypt, key);
            return Hex_2To16(resultArray); ;
        }


        /// <summary>
        /// aes加密(转换成64位)
        /// </summary>
        /// <param name="toDecrypt"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string Encrypt_64(string toDecrypt, string key)
        {
            string aes = Encrypt(toDecrypt, key);
            return Hex_Base64Code(aes);
        }


        #endregion


        #region AES解密

        /// <summary>
        ///  AES解密
        /// </summary>
        /// <param name="toDecrypt"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string Decrypt(string toDecrypt, string key)
        {
            key = getIv(key);
            byte[] keyArray = encoding.GetBytes(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.GetString(resultArray);
        }


        /// <summary>
        ///  64位加密密码->AES解密
        /// </summary>
        /// <param name="toDecrypt"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string Decrypt_64(string toDecrypt, string key)
        {
            string aes = Hex_Base64Decode(toDecrypt);
            return Decrypt(aes, key);
        }

        /// <summary>
        /// 16位加密密码->AES解密
        /// </summary>
        /// <param name="toDecrypt"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string Decrypt_16(string toDecrypt, string key)
        {
            byte[] hex2 = Hex_16To2(toDecrypt);
            string aes = Convert.ToBase64String(hex2);
            return Decrypt(aes, key);
        }
        #endregion


        #region 基础转换



        /// <summary>
        /// Base64加密
        /// </summary>
        /// <param name="Message"></param>
        /// <returns></returns>
        public string Hex_Base64Code(string Message)
        {
            byte[] bytes = encoding.GetBytes(Message);
            return Convert.ToBase64String(bytes);
        }
        /// <summary>
        /// Base64解密
        /// </summary>
        /// <param name="Message"></param>
        /// <returns></returns>
        public string Hex_Base64Decode(string Message)
        {
            byte[] bytes = Convert.FromBase64String(Message);
            return encoding.GetString(bytes);
        }











        /// <summary>   
        /// 2进制转16进制   
        /// </summary>   
        public String Hex_2To16(Byte[] bytes)
        {
            String hexString = String.Empty;
            Int32 iLength = 65535;
            if (bytes != null)
            {
                StringBuilder strB = new StringBuilder();

                if (bytes.Length < iLength)
                {
                    iLength = bytes.Length;
                }

                for (int i = 0; i < iLength; i++)
                {
                    strB.Append(bytes[i].ToString("x2"));
                }
                hexString = strB.ToString();
            }
            return hexString;
        }

        /// <summary>   
        /// 16进制转2进制   
        /// </summary>   
        public Byte[] Hex_16To2(String hexString)
        {
            if ((hexString.Length % 2) != 0)
            {
                hexString += " ";
            }
            Byte[] returnBytes = new Byte[hexString.Length / 2];
            for (Int32 i = 0; i < returnBytes.Length; i++)
            {
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            }
            return returnBytes;
        }

        #endregion
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值