1. 程式人生 > >RSA前後端加密

RSA前後端加密

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;


import javax.crypto.Cipher;




import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class RsaHelper {
	
	private static PrivateKey PRIVATE_KEY;
	
	static{
		try {
			PRIVATE_KEY=getPrivateKey(PropertiesUtil.getValue("rsa.private.key", "")); //獲取properties中配好的私鑰
		} catch (Exception e) {
			PRIVATE_KEY=null;
		}
	}
	
	/**
	 * 生成RSA金鑰對(預設金鑰長度為1024)
	 * 
	 * @return
	 */
	public static KeyPair generateRSAKeyPair() {
		return generateRSAKeyPair(1024);
	}

	/**
	 * 生成RSA金鑰對
	 * 
	 * @param keyLength  金鑰長度
	 *            
	 * @return
	 */
	public static KeyPair generateRSAKeyPair(int keyLength) {
		try {
			KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
			kpg.initialize(keyLength);
			return kpg.genKeyPair();
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException(e);
		}
	}

	
	// 用公鑰加密
	public static byte[] encryptData(byte[] data, PublicKey pubKey) {
		try {
			Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
			cipher.init(Cipher.ENCRYPT_MODE, pubKey);
			return cipher.doFinal(data);
		} catch (Exception e) {
			return null;
		}
	}
	/**
	 * 
	 * 用公鑰加密
	 * @param str     待加密字串
	 * @param enCode  字串編碼格式
	 * @param pubKey  公鑰
	 * @return        加密後字串
	 */
	public static String encryptData(String str,String enCode, PublicKey pubKey) {
		try {
			byte[] data=str.getBytes(enCode);
			Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
			cipher.init(Cipher.ENCRYPT_MODE, pubKey);
			return (new BASE64Encoder()).encode(cipher.doFinal(data));
		} catch (Exception e) {
			return null;
		}
	}

	// 用私鑰解密
	public static byte[] decryptData(byte[] encryptedData, PrivateKey priKey) {
		try {
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, priKey);
			return cipher.doFinal(encryptedData);
		} catch (Exception e) {
			return null;
		}
	}
	/**
	 * 用私鑰解密
	 * @author suo
	 * @param encryptedStr 待解密字串
	 * @param enCode       字串編碼格式
	 * @param priKey       私鑰
	 * @return  解密後字串
	 */
	public static String decryptData(String encryptedStr,String enCode, PrivateKey priKey) {
		try {
			byte[] encryptedData=(new BASE64Decoder()).decodeBuffer(encryptedStr);
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, priKey);
			return new String(cipher.doFinal(encryptedData),enCode);
		} catch (Exception e) {
			throw  new RuntimeException(e);
		}
	}
	/**
	 * 使用既有的私鑰進行解密
	 * @param encryptedStr
	 * @param enCode
	 * @return
	 */
	public static String decryptData(String encryptedStr,String enCode) {
		return decryptData(encryptedStr, enCode, PRIVATE_KEY);
	}
	
	

	/**
	 * 根據指定私鑰對資料進行簽名(預設簽名演算法為"SHA1withRSA")
	 * 
	 * @param data
	 *            要簽名的資料
	 * @param priKey
	 *            私鑰
	 * @return
	 */
	public static byte[] signData(byte[] data, PrivateKey priKey) {
		return signData(data, priKey, "SHA1withRSA");
	}

	/**
	 * 根據指定私鑰和演算法對資料進行簽名
	 * 
	 * @param data
	 *            要簽名的資料
	 * @param priKey
	 *            私鑰
	 * @param algorithm
	 *            簽名演算法
	 * @return
	 */
	public static byte[] signData(byte[] data, PrivateKey priKey,
			String algorithm) {
		try {
			Signature signature = Signature.getInstance(algorithm);
			signature.initSign(priKey);
			signature.update(data);
			return signature.sign();
		} catch (Exception ex) {
			return null;
		}
	}

	/**
	 * 用指定的公鑰進行簽名驗證(預設簽名演算法為"SHA1withRSA")
	 * 
	 * @param data
	 *            資料
	 * @param sign
	 *            簽名結果
	 * @param pubKey
	 *            公鑰
	 * @return
	 */
	public static boolean verifySign(byte[] data, byte[] sign, PublicKey pubKey) {
		return verifySign(data, sign, pubKey, "SHA1withRSA");
	}

	/**
	 * 
	 * @param data
	 *            資料
	 * @param sign
	 *            簽名結果
	 * @param pubKey
	 *            公鑰
	 * @param algorithm
	 *            簽名演算法
	 * @return
	 */
	public static boolean verifySign(byte[] data, byte[] sign,
			PublicKey pubKey, String algorithm) {
		try {
			Signature signature = Signature.getInstance(algorithm);
			signature.initVerify(pubKey);
			signature.update(data);
			return signature.verify(sign);
		} catch (Exception ex) {
			return false;
		}
	}
	/**
 * 從base64字串獲取公鑰
 * @param key
 * @return
 * @throws Exception
 */
	public static PublicKey getPublicKey(String key) throws Exception {
         byte[] keyBytes;
         keyBytes = (new BASE64Decoder()).decodeBuffer(key);

         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
         PublicKey publicKey = keyFactory.generatePublic(keySpec);
         return publicKey;
        }
	/**
 * 從base64字串獲取私鑰
 * @param key
 * @return
 * @throws Exception
 */
	public static PrivateKey getPrivateKey(String key) throws Exception{
        byte[] keyBytes;
        keyBytes = (new BASE64Decoder()).decodeBuffer(key);

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }
	/**
 * 把金鑰轉成base64字串
 * @param key
 * @return
 * @throws Exception
 */
	public static String getKeyString(Key key) throws Exception {
         byte[] keyBytes = key.getEncoded();
         String s = (new BASE64Encoder()).encode(keyBytes);
         return s;
    }
}

三、前端js程式碼