AES和RSA:加密解密

最近生活乱七八糟,什么都懒上了天。感觉自己会的东西好少
领导新分配了一个任务,让我将http换成https,对参数进行加密
可选择有两个加密算法AESRSA
由于公司内部使用,且数据量大,可以用私钥。于是就用AES。

AES

1.概念

AES又叫Rijndael算法,是DES升级的加密标准,运行要求低,不需计算机有非常高的处理能力和大的内存;

操作可以很容易的抵御时间和空间的攻击,在不同的运行环境下始终保持良好的性能;

AES密钥长度:最长只有256bit,可用软件和硬件实现高速处理;

密钥管理:要求在通信前对密钥进行秘密分配,解密的私钥必须通过网络传送至加密数据接收方;

AES加密速度很快;

对称加密;

2.帮助类
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.util.encrypt.Base64;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AesEncrypt {
	private static final String AES_STR = "AES";
	private static final String SHA1PRNG_STR = "SHA1PRNG";
	
	public static String encrypt(String bef_aes, String password) {
		byte[] byteContent = null;
		try {
			byteContent = bef_aes.getBytes("utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return encrypt(byteContent,password);
	}
	public static String encrypt(byte[] content, String password) {
		try {
			SecretKey secretKey = getKey(password);
			byte[] enCodeFormat = secretKey.getEncoded();
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, AES_STR);
			Cipher cipher = Cipher.getInstance(AES_STR);// 创建密码器
			cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
			byte[] result = cipher.doFinal(content);
			String aft_aes = parseByte2HexStr(result);
			return aft_aes; // 加密
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static String decrypt(String aft_aes_base64, String password,String charset){
		String aft_aes="";
		try {
			aft_aes = Base64.decode(aft_aes_base64);
			
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return decrypt(aft_aes,password);
		
	}
	public static String decrypt(String aft_aes, String password) {
		try {
			byte[] content = parseHexStr2Byte(aft_aes);
			SecretKey secretKey = getKey(password);
			byte[] enCodeFormat = secretKey.getEncoded();
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, AES_STR);
			Cipher cipher = Cipher.getInstance(AES_STR);// 创建密码器
			cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
			byte[] result = cipher.doFinal(content);
			String bef_aes = new String(result);
			return bef_aes; // 加密
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	public static String parseByte2HexStr(byte buf[]) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < buf.length; i++) {
			String hex = Integer.toHexString(buf[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}
	public static byte[] parseHexStr2Byte(String hexStr) {   
        if (hexStr.length() < 1)   
                return null;   
        byte[] result = new byte[hexStr.length()/2];   
        for (int i = 0;i< hexStr.length()/2; i++) {   
                int value = Integer.parseInt(hexStr.substring(i*2, i*2+2), 16);   
                result[i] = (byte)value;   
        }   
        return result;   
}  
	public static SecretKey getKey(String strKey) {
	    try {	    	
	        KeyGenerator _generator = KeyGenerator.getInstance(AES_STR);
	        SecureRandom secureRandom = SecureRandom.getInstance(SHA1PRNG_STR);
	        secureRandom.setSeed(strKey.getBytes());
	        _generator.init(128,secureRandom);
	       	return _generator.generateKey();
	    } catch (Exception e) {
	        throw new RuntimeException("初始化密钥出现异常");
	    }
	  }	
	
	  /**
		  * AES的加密函数
		  * @param str 传入需要加密的字符
		  * @param key 传入一个16位长度的密钥。否则报错
		  * @return 执行成功返回加密结果,否则报错
		  * @throws Exception 抛出一个加密异常
		  */
		 @SuppressWarnings("restriction")
		public static String aesEncrypt(String str, String key) throws Exception {
		        if (str == null || key == null) return null;
		        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
		        byte[] bytes = cipher.doFinal(str.getBytes("utf-8"));
		        return new BASE64Encoder().encode(bytes);
		    }
		 /**
		  * AES的解密函数
		  * @param str 传入需要解密的字符
		  * @param key 传入一个16位长度的密钥。否则报错
		  * @return 执行成功返回加密结果,否则报错
		  * @throws Exception 抛出一个解密异常
		  */
		 @SuppressWarnings("restriction")
		    public static String aesDecrypt(String str, String key) throws Exception {
		        if (str == null || key == null) return null;
		        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
		        byte[] bytes = new BASE64Decoder().decodeBuffer(str);
		        bytes = cipher.doFinal(bytes);
		        return new String(bytes, "utf-8");
		    } 

}
3.controller
//如果参数的加密后的字节流,则需要先解密然后转Object
@RequestMapping(value="/ts",method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody String aa(@RequestBody  String param)
{
byte[] byteContent = param.getBytes("utf-8");
String key="ABCDEFGHIJKLMNRS";//秘钥
String  dataJson="";//加密内容
//去除Base64 和hex:用字符串形式看二进制代码 将二进制转化成16进制
String simpleResult = AesEncrypt.aesEncrypt(dataJson, key);//加密后的密文
String simpleContent= AesEncrypt.aesDecrypt(dataJson, key);//解密后的内容
String result = AesEncrypt.encrypt(dataJson, key);//加密后的密文
String content= AesEncrypt.decrypt(dataJson, key);//解密后的内容
}

RSA

1.概念

是公开密钥系统的代表;

安全性:建立在具有大素数因子的合数,其因子分解困难这一法则之上;

处理速度慢;

密钥管理:加解密过程中不必网络传输保密的密钥;密钥管理优于AES算法;

RSA加解密速度慢,不适合大量数据文件加密;

公钥加密 私钥解密

钥加密 公钥解密 使用签名确定是否为该私钥加密

2.使用
 //非对称密钥算法
    public static final String KEY_ALGORITHM = "RSA";


    /**
     * 密钥长度,DH算法的默认密钥长度是1024
     * 密钥长度必须是64的倍数,在512到65536位之间
     */
    private static final int KEY_SIZE = 512;
    //公钥
    private static final String PUBLIC_KEY = "RSAPublicKey";

    //私钥
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * 初始化密钥对
     *
     * @return Map 甲方密钥的Map
     */
    public static Map<String, Object> initKey() throws Exception {
        //实例化密钥生成器
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        //初始化密钥生成器
        keyPairGenerator.initialize(KEY_SIZE);
        //生成密钥对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        //甲方公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        //甲方私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        //将密钥存储在map中
        Map<String, Object> keyMap = new HashMap<String, Object>();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;

    }


    /**
     * 私钥加密
     *
     * @param data 待加密数据
     * @param key       密钥
     * @return byte[] 加密数据
     */
    public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {

        //取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //生成私钥
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        //数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    /**
     * 公钥加密
     *
     * @param data 待加密数据
     * @param key       密钥
     * @return byte[] 加密数据
     */
    public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {

        //实例化密钥工厂
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //初始化公钥
        //密钥材料转换
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
        //产生公钥
        PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);

        //数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

    /**
     * 私钥解密
     *
     * @param data 待解密数据
     * @param key  密钥
     * @return byte[] 解密数据
     */
    public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
        //取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //生成私钥
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        //数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    /**
     * 公钥解密
     *
     * @param data 待解密数据
     * @param key  密钥
     * @return byte[] 解密数据
     */
    public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {

        //实例化密钥工厂
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //初始化公钥
        //密钥材料转换
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
        //产生公钥
        PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
        //数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

    /**
     * 取得私钥
     *
     * @param keyMap 密钥map
     * @return byte[] 私钥
     */
    public static byte[] getPrivateKey(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        return key.getEncoded();
    }

    /**
     * 取得公钥
     *
     * @param keyMap 密钥map
     * @return byte[] 公钥
     */
    public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        return key.getEncoded();
    }

使用
 //初始化密钥
      //生成密钥对
      Map<String, Object> keyMap = initKey();
      //公钥
      byte[] publicKey = getPublicKey(keyMap);

      //私钥
      byte[] privateKey = getPrivateKey(keyMap);
      System.out.println("公钥:/n" + Base64.encodeBase64String(publicKey));
      System.out.println("私钥:/n" + Base64.encodeBase64String(privateKey));

      System.out.println("================密钥对构造完毕,甲方将公钥公布给乙方,开始进行加密数据的传输=============");
      String str = "RSA密码交换算法";
      System.out.println("/n===========甲方向乙方发送加密数据==============");
      System.out.println("原文:" + str);
      //甲方进行数据的加密
      byte[] code1 = encryptByPrivateKey(str.getBytes(), privateKey);
      System.out.println("加密后的数据:" + Base64.encodeBase64String(code1));
      System.out.println("===========乙方使用甲方提供的公钥对数据进行解密==============");
      //乙方进行数据的解密
      byte[] decode1 = decryptByPublicKey(code1, publicKey);
      System.out.println("乙方解密后的数据:" + new String(decode1) + "/n/n");

      System.out.println("===========反向进行操作,乙方向甲方发送数据==============/n/n");

      str = "乙方向甲方发送数据RSA算法";

      System.out.println("原文:" + str);

      //乙方使用公钥对数据进行加密
      byte[] code2 =encryptByPublicKey(str.getBytes(), publicKey);
      System.out.println("===========乙方使用公钥对数据进行加密==============");
      System.out.println("加密后的数据:" + Base64.encodeBase64String(code2));

      System.out.println("=============乙方将数据传送给甲方======================");
      System.out.println("===========甲方使用私钥对数据进行解密==============");

      //甲方使用私钥对数据进行解密
      byte[] decode2 = decryptByPrivateKey(code2, privateKey);

      System.out.println("甲方解密后的数据:" + new String(decode2));
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值