JAVA-RSA/DES加密兑现备忘

JAVA-RSA/DES加密实现备忘.

1. RsaEncoder.java

public class RsaEncoder {

	private PublicKey rsaPublicKey;
	
	private  Cipher cipher;
	
	// 1024位RSA加密算法中,当加密明文长度超过117个字节后,会出现异常,所以采用分段加密
	private final static int PT_LEN = 117;
	private final static String SPRIT_CHAR="|";//分段加密/解密,段落分割符,

	private RsaEncoder(String publicKey) throws Exception{
		cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		this.rsaPublicKey = this.generatePublic(publicKey);
	}
	
	private  PublicKey generatePublic(String key) throws Exception {
		byte[] keyBytes = Base64.decodeBase64(key);//UTF-8

		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PublicKey publicKey = keyFactory.generatePublic(keySpec);
		return publicKey;
	}
	
	/**
	 * 加密输入的明文字符串
	 * 当value的字节长度大于117,将会采用分段加密,即依次对117个字节,加密,并通过"|"对段落进行分割,请解密者注意
	 * @param value 加密后的字符串 1024个字节长度
	 * @return
	 */
	public String encrypt(String value) throws IOException{
		if(StringUtils.isEmpty(value)){
			return null;
		}
		return encryptBySeg(value.getBytes());
	}
	
	/**
	 * 分段加密
	 * @param plainText,各个段落以'|'分割
	 * @return
	 * @throws IOException
	 */
	private String encryptBySeg(byte[] plainText) throws IOException{
		//获取加密段落个数
		int length = plainText.length;//
		int mod = length %PT_LEN;//余数
		int ptime = length /PT_LEN;//段数
		int ptimes = (mod == 0 ? ptime : ptime +1);
		StringBuffer sb = new StringBuffer();
		int i = 0;
		while(i < ptimes){
			int from = i * PT_LEN;
			int to = Math.min(length, (i+1)*PT_LEN);
			byte[] temp = Arrays.copyOfRange(plainText,from, to);
			sb.append(Base64.encodeBase64String(encrypt(temp)));//apache commons-codec
			if(i != (ptimes - 1)){
				sb.append(SPRIT_CHAR);
			}
			i++;
		}
		return sb.toString();

	}
	/**
	 * 加密
	 * @param plainTextArray
	 * @return
	 */
	private byte[] encrypt(byte[] plainTextArray) {
		try {
			cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);
			return cipher.doFinal(plainTextArray);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 根据公钥,获取加密工具类实例
	 * @param publicKey
	 * @return
	 */
	public static RsaEncoder getInstance(String publicKey) throws Exception{
		if(StringUtils.isEmpty(publicKey)){
			return null;
		}
		return new RsaEncoder(publicKey);
	}
	
	/**
	 * 重置加密key
	 * @param publicKey
	 */
	public synchronized void reset(String publicKey) throws Exception{
		this.rsaPublicKey = this.generatePublic(publicKey);
	}
}

2.RsaDecoder.java

public class RsaDecoder {

	private PrivateKey rsaPrivateKey;
	private  Cipher cipher;
	private final static String SPRIT_CHAR="|";//分段加密/解密,段落分割符
	private RsaDecoder(String privateKey) throws Exception{
		cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		this.rsaPrivateKey = this.generatePrivate(privateKey);
	}
	/**
	 * 获取私钥,根据已经生成的合格的RSA私钥字符串,转化成RSAPrivateKey对象,(PKCS8EncodedKeySpec)
	 * @param key
	 * @return
	 * @throws Exception
	 */
	private PrivateKey generatePrivate(String key) throws Exception {
		byte[] keyBytes = Base64.decodeBase64(key);

		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		return privateKey;
	}

	/**
	 * 解密
	 *
	 * @param encrypt 加密后的二进制字节
	 *            
	 * @return 解密后的二进制
	 */
	private  byte[] dencrypt(byte[] encrypt) {
		try {
			cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
			byte[] decryptByteArray = cipher.doFinal(encrypt);
			return decryptByteArray;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 对加密数据进行解密,自动分段
	 *
	 * @param plainText
	 */
	public  String dencrypt(String plainTextA) {
		StringTokenizer tokenizer = new StringTokenizer(plainTextA,SPRIT_CHAR);
		StringBuffer sb = new StringBuffer();
		while (tokenizer.hasMoreTokens()) {
			byte[] tmp;
			String tmpBase64Str = (String) tokenizer.nextElement();
			try {
				tmp = Base64.decodeBase64(getFromatBase64String(tmpBase64Str,1));
				tmp = dencrypt(tmp);
				sb.append(new String(tmp));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		//替换空格
		return sb.toString().replace("\u0000","");

	}

	/**
	 *
	 * @param str
	 * @return
	 */
	public String getFromatBase64String(String str,int times){
		int timesModes = (int) (Math.pow(1.5, times-1)*10);
		//这个数字是由RSA1024位 及base 64增大0.5倍,具体计算公式为:rsa密钥长度/8*(1.5);
		final int  subLength = 172 * timesModes/10;
		return str.substring(str.length()-subLength, str.length());

	}

	/**
	 * 根据私钥获取解密对象
	 * @param privateKey
	 * @return
	 * @throws Exception
	 */
	public static RsaDecoder getInstance(String privateKey) throws Exception{
		if(StringUtils.isEmpty(privateKey)){
			return null;
		}
		return new RsaDecoder(privateKey);
	}
	
	/**
	 * 重置加密key
	 * @param publicKey
	 */
	public void reset(String privateKey) throws Exception{
		this.rsaPrivateKey = this.generatePrivate(privateKey);
	}
}

3.RsaBuilder.java

public class RsaBuilder {

	public static final int KEY_SIZE = 1024;
	
	/**
	 * 生成密钥对,注意需要对public key进行位运算.
	 * @return
	 */
	public static KeyPair generateKeyPair(){
		try {
			KeyPairGenerator keyPairGen = (KeyPairGenerator) KeyPairGenerator.getInstance("RSA");
			keyPairGen.initialize(KEY_SIZE, new SecureRandom());
			KeyPair keyPair = keyPairGen.genKeyPair();
			return keyPair;
		} catch (NoSuchAlgorithmException e) {
			return null;
		}
	}
	
	public static void main(String[] args) throws Exception{
		KeyPair keyPair = RsaBuilder.generateKeyPair();
		PrivateKey privateKey = keyPair.getPrivate();
		String privateKeyStr = Base64.encodeBase64String(privateKey.getEncoded());
		System.out.println("----Private Key--");
		System.out.println(privateKeyStr);
		PublicKey publicKey = keyPair.getPublic();
		String publicKeyStr = Base64.encodeBase64String(publicKey.getEncoded());
		System.out.println("----Public Key--");
		System.out.println(publicKeyStr);
		String tmp = "123456789";
		RsaEncoder rsaEncoder = RsaEncoder.getInstance(publicKeyStr);
		String result = rsaEncoder.encrypt(tmp);
		RsaDecoder rsaDecoder = RsaDecoder.getInstance(privateKeyStr);
		System.out.println(rsaDecoder.dencrypt(result));
		
	}
}

4.DesEncoder.java

public class DesEncoder {
	private static final String DES = "DES";
	private static final String PADDING = "DES/ECB/PKCS5Padding";
	private static final String DEFAULT_ENCODING = "utf-8";
	
	public final static String encrypt(String code, String key) {
		try {
			return Base64.encodeBase64String(encrypt(code.getBytes(DEFAULT_ENCODING), key
					.getBytes(DEFAULT_ENCODING)));
		} catch (Exception e) {
			//
		}
		return null;

	}
	
	public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
		SecureRandom sr = new SecureRandom();
		DESKeySpec dks = new DESKeySpec(key);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		Cipher cipher = Cipher.getInstance(PADDING);
		cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
		return cipher.doFinal(src);

	}
	public final static String decrypt(String data, String key) {
		try {
			//base64,default-charset is UTF-8
			return new String(decrypt(Base64.decodeBase64(data),
			key.getBytes(DEFAULT_ENCODING)), DEFAULT_ENCODING);

		} catch (Exception e) {
			//
		}
		return null;
	}
	
	public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
		SecureRandom sr = new SecureRandom();
		DESKeySpec dks = new DESKeySpec(key);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		Cipher cipher = Cipher.getInstance(PADDING);
		cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
		return cipher.doFinal(src);
	}

	
	public static void main(String[] args) {
		String tmp = DesEncoder.encrypt("821", "yc2JffcREheFQlYFIAY5f9sY7uf*o");
        System.out.print(DesEncoder.decrypt(tmp, "yc2JffcREheFQlYFIAY5f9sY7uf*o"));
	}

}