`

Java RSA 加密 解密 签名 验签

    博客分类:
  • Java
阅读更多
1. 加密的作用

1)明文变密文(你不知道密钥是很难解密的);
2)数据的一致性(hash值一样);
3)数据的可信任性(验签)。

2. 两种不同的加密与解密

1)对称加密:加密与解密使用相同的密钥,处理速度快;
2)非对称加密:加密与解密使用不同的密钥(生对生成),处理速度不及对称加密。

3.在非对称加密中,究竟是公钥加密还是私钥加密的问题

1)如果只是用加密的用途
   公钥加密,私钥解密(私钥只有一个,公钥大家都知道)。
2)如果用验签
   私钥加密,公钥解密(解密的来源是私钥,其它的来源是不可信任的)。

下面是两个工具类。
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
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.SecureRandom;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;

public class RSAHelper {
	public static final String KEY_ALGORITHM = "RSA";
	private static final int KEY_LENGTH = 1024;
	public static final String PUBLIC_KEY = "PublicKey";
	public static final String PRIVATE_KEY = "PrivateKey";
	private static final int MAX_ENCRYPT_BLOCK = 117;
	private static final int MAX_DECRYPT_BLOCK = 128;
	private static final String SIGNATURE_ALGORITHM = "MD5withRSA";

	public RSAHelper() {
	}

	public static void generateKeyPair(Map<String, Object> keyMap) {
		boolean result = false;

		KeyPairGenerator keyPairGenerator = null;
		try {
			keyPairGenerator = KeyPairGenerator.getInstance("RSA");
			result = true;
		} catch (NoSuchAlgorithmException ex) {
			Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,
					ex);
		}

		if (result) {
			SecureRandom secureRandom = new SecureRandom();

			String currentDateTime = new SimpleDateFormat("yyyyMMddHHmmssSSS")
					.format(new Date());
			secureRandom.setSeed(currentDateTime.getBytes());

			keyPairGenerator.initialize(1024, secureRandom);

			KeyPair keyPair = keyPairGenerator.genKeyPair();

			PublicKey publicKey = keyPair.getPublic();
			PrivateKey privateKey = keyPair.getPrivate();

			keyMap.put("PublicKey", publicKey.getEncoded());
			keyMap.put("PrivateKey", privateKey.getEncoded());
		}
	}

	public static void saveKeyPair(Map<String, Object> keyPair,
			String publicKeyFileName, String privateKeyFileName) {
		try {
			FileOutputStream fileOutputStream = new FileOutputStream(
					publicKeyFileName);
			byte[] publicKey = (byte[]) keyPair.get("PublicKey");
			fileOutputStream.write(publicKey);
			fileOutputStream.close();
		} catch (FileNotFoundException ex) {
			Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (IOException ex) {
			Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,
					ex);
		}

		try {
			FileOutputStream fileOutputStream = new FileOutputStream(
					privateKeyFileName);
			byte[] privateKey = (byte[]) keyPair.get("PrivateKey");
			fileOutputStream.write(privateKey);
			fileOutputStream.close();
		} catch (FileNotFoundException ex) {
			Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (IOException ex) {
			Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,
					ex);
		}
	}

	public static byte[] getKey(String keyFileName) {
		byte[] keyBytes = null;
		try {
			File file = new File(keyFileName);
			FileInputStream fileInputStream = new FileInputStream(file);
			DataInputStream dataInputStream = new DataInputStream(
					fileInputStream);

			keyBytes = new byte[(int) file.length()];

			dataInputStream.readFully(keyBytes);

			dataInputStream.close();
			fileInputStream.close();
		} catch (FileNotFoundException ex) {
			Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (IOException ex) {
			Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,
					ex);
		}

		return keyBytes;
	}

	public static byte[] encryptWithPublicKey(byte[] data, int offSet,
			int length, byte[] keyBytes) throws Exception {
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		Key publicK = keyFactory.generatePublic(x509KeySpec);

		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(1, publicK);
		ByteArrayOutputStream out = new ByteArrayOutputStream();

		int i = 0;

		while (length - offSet > 0) {
			byte[] cache;
			if (length - offSet > 117) {
				cache = cipher.doFinal(data, offSet, 117);
			} else {
				cache = cipher.doFinal(data, offSet, length - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * 117;
		}
		byte[] encryptedData = out.toByteArray();
		out.close();
		return encryptedData;
	}

	public static byte[] encryptWithPrivateKey(byte[] data, int offSet,
			int length, byte[] keyBytes) throws Exception {
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(1, privateK);
		ByteArrayOutputStream out = new ByteArrayOutputStream();

		int i = 0;

		while (length - offSet > 0) {
			byte[] cache;
			if (length - offSet > 117) {
				cache = cipher.doFinal(data, offSet, 117);
			} else {
				cache = cipher.doFinal(data, offSet, length - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * 117;
		}
		byte[] encryptedData = out.toByteArray();
		out.close();
		return encryptedData;
	}

	public static byte[] decryptWithPublicKey(byte[] data, int offSet,
			int length, byte[] keyBytes) throws Exception {
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		Key publicK = keyFactory.generatePublic(x509KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(2, publicK);
		ByteArrayOutputStream out = new ByteArrayOutputStream();

		int i = 0;

		while (length - offSet > 0) {
			byte[] cache;
			if (length - offSet > 128) {
				cache = cipher.doFinal(data, offSet, 128);
			} else {
				cache = cipher.doFinal(data, offSet, length - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * 128;
		}
		byte[] decryptedData = out.toByteArray();
		out.close();
		return decryptedData;
	}

	public static byte[] decryptWithPrivateKey(byte[] data, int offSet,
			int length, byte[] keyBytes) throws Exception {
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(2, privateK);
		ByteArrayOutputStream out = new ByteArrayOutputStream();

		int i = 0;

		while (length - offSet > 0) {
			byte[] cache;
			if (length - offSet > 128) {
				cache = cipher.doFinal(data, offSet, 128);
			} else {
				cache = cipher.doFinal(data, offSet, length - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * 128;
		}
		byte[] decryptedData = out.toByteArray();
		out.close();
		return decryptedData;
	}

	public static byte[] sign(byte[] data, int offset, int length,
			byte[] privateKeyBytes) {
		byte[] signedData = null;
		try {
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
					privateKeyBytes);

			KeyFactory keyFactory = KeyFactory.getInstance("RSA");

			PrivateKey privateKey = keyFactory
					.generatePrivate(pkcs8EncodedKeySpec);

			Signature signature = Signature.getInstance("MD5withRSA");

			signature.initSign(privateKey);

			signature.update(data, offset, length);

			signedData = signature.sign();
		} catch (Exception ex) {
			Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,
					ex);
		}

		return signedData;
	}

	public static boolean verify(byte[] data, int offset, int length,
			byte[] publicKeyBytes, byte[] dataSignature) {
		boolean result = false;
		try {
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
					publicKeyBytes);

			KeyFactory keyFactory = KeyFactory.getInstance("RSA");

			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

			Signature signature = Signature.getInstance("MD5withRSA");

			signature.initVerify(publicKey);

			signature.update(data, offset, length);

			result = signature.verify(dataSignature);
		} catch (Exception ex) {
			Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,
					ex);
		}

		return result;
	}
}


import com.adph.jms.Base64Utils;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

public class RSAKeyUtils {
	private static String RAS_PUBLICKEY_PATH = "D://security.key";
	private static String RSA_PRIVATEKEY_PATH= "D://security.crt";

	public RSAKeyUtils() {
	}

	protected static void init(String RAS_PUBLICKEY_PATH,
			String RSA_PRIVATEKEY_PATH) {
		try {
			FileUtils.forceMkdir(new File(new File(RAS_PUBLICKEY_PATH)
					.getParent()));
			Map<String, Object> keyPair = new HashMap();
			RSAHelper.generateKeyPair(keyPair);
			RSAHelper.saveKeyPair(keyPair, RAS_PUBLICKEY_PATH,
					RSA_PRIVATEKEY_PATH);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void setKeyPath(String keyPath) {
		RAS_PUBLICKEY_PATH = keyPath;
	}

	public static void setCrtPath(String crtPath) {
		RSA_PRIVATEKEY_PATH = crtPath;
	}

	public static String encByPublicKey(String data) {
		String dataBack = "";
		try {
			if (!StringUtils.isEmpty(data)) {
				byte[] Bytes = RSAHelper.encryptWithPublicKey(data.getBytes(),
						0, data.getBytes().length,
						RSAHelper.getKey(RAS_PUBLICKEY_PATH));
				dataBack = Base64Utils.encode(Bytes);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dataBack;
	}

	public static String encByPrivateKey(String data) {
		String dataBack = "";
		try {
			if (!StringUtils.isEmpty(data)) {
				byte[] Bytes = RSAHelper.encryptWithPrivateKey(data.getBytes(),
						0, data.getBytes().length,
						RSAHelper.getKey(RSA_PRIVATEKEY_PATH));
				dataBack = Base64Utils.encode(Bytes);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dataBack;
	}

	public static String decByPublicKey(String data) {
		String dataBack = "";
		try {
			if (!StringUtils.isEmpty(data)) {
				byte[] Bytes = RSAHelper.decryptWithPublicKey(
						Base64Utils.decode(data), 0,
						Base64Utils.decode(data).length,
						RSAHelper.getKey(RAS_PUBLICKEY_PATH));
				dataBack = new String(Bytes);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dataBack;
	}

	public static String decByPrivateKey(String data) {
		String dataBack = "";
		try {
			if (!StringUtils.isEmpty(data)) {
				byte[] Bytes = RSAHelper.decryptWithPrivateKey(
						Base64Utils.decode(data), 0,
						Base64Utils.decode(data).length,
						RSAHelper.getKey(RSA_PRIVATEKEY_PATH));
				dataBack = new String(Bytes);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dataBack;
	}

	public static String doSignPrivateKey(String data) {
		String dataBack = "";
		try {
			if (!StringUtils.isEmpty(data)) {
				byte[] Bytes = RSAHelper.sign(data.getBytes(), 0,
						data.getBytes().length,
						RSAHelper.getKey(RSA_PRIVATEKEY_PATH));
				dataBack = Base64Utils.encode(Bytes);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dataBack;
	}

	public static boolean doVerifyPublicKey(String data, String sign) {
		Boolean returnFlag = Boolean.FALSE;
		if ((StringUtils.isEmpty(data)) || (StringUtils.isEmpty(sign))) {
			return Boolean.FALSE.booleanValue();
		}
		try {
			returnFlag = Boolean.valueOf(RSAHelper.verify(data.getBytes(), 0,
					data.getBytes().length,
					RSAHelper.getKey(RAS_PUBLICKEY_PATH),
					Base64Utils.decode(sign)));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return returnFlag.booleanValue();
	}

//	public static void main(String[] args) {
//		init("D://security.key", "D://security.crt");
//	}
}


写一个例子测试下。注意:先要运行上面main方法,使其生成security.key和security.crt。

public class EncTest {
	public static void main(String[] args) throws Exception {
		String text = "Hello World";
		String enc = RSAKeyUtils.encByPublicKey(text);
		System.out.println("加密数据:" + enc);
		System.out.println("解密数据:" + RSAKeyUtils.decByPrivateKey(enc));
		String sign=RSAKeyUtils.doSignPrivateKey(text);
		System.out.println("签名:"+sign);
		System.out.println("验签结果:"+RSAKeyUtils.doVerifyPublicKey(text, sign));
	}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics