首页 > 代码库 > JAVA 非对称加密算法RSA

JAVA 非对称加密算法RSA

非对称加密算法 RSA过程 : 以甲乙双方为例
  1、初始化密钥 构建密钥对,生成公钥、私钥保存到keymap中
    KeyPairGenerator ---> KeyPair --> RSAPublicKey、RSAPrivateKey
  2、甲方使用私钥加密, 加密后在用私钥对加密数据进行数据签名,然后发送给乙方
    RSACoder.encryptByPrivateKey(data, privateKey);
    RSACoder.sign(encodedData, privateKey);
  3、乙方则通过公钥验证签名的加密数据,如果验证正确则在通过公钥对加密数据进行解密
    RSACoder.verify(encodedData, publicKey, sign);
    RSACoder.decryptByPublicKey(encodedData, publicKey);
   4、乙方在通过公钥加密发送给甲方
    RSACoder.encryptByPublicKey(decodedData, publicKey);
  5、甲方通过私钥解密该数据
    RSACoder.decryptPrivateKey(encodedData, privateKey);
流程图如下:

技术分享

技术分享

技术分享

java代码实现如下:

package com.bank.utils;import java.security.MessageDigest;import javax.crypto.KeyGenerator;import javax.crypto.Mac;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;public abstract class Coder {	public static final String KEY_SHA = "SHA";	public static final String KEY_MD5 = "MD5";		/**      * MAC算法可选以下多种算法      *       * <pre>      * HmacMD5       * HmacSHA1       * HmacSHA256       * HmacSHA384       * HmacSHA512      * </pre>      */  	public static final String KEY_MAC = "HmacMD5";		/**	 * BASE64解密	 * @param key	 * @return	 * @throws Exception	 */	public static byte[] decryptBASE64( String key ) throws Exception{		return (new BASE64Decoder()).decodeBuffer(key);	}		/**	 * BASE64加密	 * @param key	 * @return	 * @throws Exception	 */	public static String encryptBASE64( byte[] key) throws Exception{		return (new BASE64Encoder()).encodeBuffer(key);	}		/**	 * MD5 加密	 * @param data	 * @return	 * @throws Exception	 */	public static byte[] encryptMD5( byte[] data) throws Exception {		MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);		md5.update(data);				return md5.digest();	}		/**	 * SHA 加密	 * @param data	 * @return	 * @throws Exception	 */	public static byte[] encryptSHA( byte[] data) throws Exception {		MessageDigest sha = MessageDigest.getInstance(KEY_SHA);		sha.update(data);				return sha.digest();	}		/**      * 初始化HMAC密钥      *       * @return      * @throws Exception      */  	public static String initMacKey() throws Exception{		KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);				SecretKey secretKey = keyGenerator.generateKey();		return encryptBASE64(secretKey.getEncoded());	}		/**	 * HMAC  加密	 * @param data	 * @param key	 * @return	 * @throws Exception	 */	public static byte[] encryptHMAC( byte[] data, String key) throws Exception{		SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);		Mac mac = Mac.getInstance(secretKey.getAlgorithm());		mac.init(secretKey);		return mac.doFinal(data);	}}

  

package com.bank.utils;import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;import javax.crypto.Cipher;public abstract class RSACoder extends Coder{	public static final String KEY_ALGORITHM = "RSA";	public static final String SIGNATURE_ALGORITHM = "MD5withRSA";		private static final String PUBLIC_KEY = "RSAPublicKey";	private static final String PRIVATE_KEY = "RSAPrivatekey";		/**	 * 用私钥对信息生成数字签名	 * @param data 加密数据	 * @param privateKey 私钥	 * @return	 * @throws Exception	 */	public static String sign(byte[] data, String privateKey) throws Exception {		//解密由base64编码的私钥		byte[] keyBytes = decryptBASE64(privateKey);				PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);				KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);				//取私钥对象		PrivateKey pKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);				//用私钥生成数字签名		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);		signature.initSign(pKey);		signature.update(data);				return encryptBASE64(signature.sign());	}		/**	 * 校验数字签名	 * @param data 加密数据	 * @param publicKey 公钥	 * @param sign 数字签名	 * @return	 * @throws Exception	 */	public static boolean verify(byte[] data, String publicKey, String sign) throws Exception{				//解密有base64编码的公钥		byte[] keyBytes = decryptBASE64(publicKey);				X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);				KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);				//取公钥对象		PublicKey pKey = keyFactory.generatePublic(keySpec);				Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);		signature.initVerify(pKey);		signature.update(data);		//验证签名是否正常		return signature.verify(decryptBASE64(sign));	}		/**	 * 解密 	 * 	用私钥解密	 * @param data 加密数据	 * @param key	 * @return	 * @throws Exception	 */	public static byte[] decryptPrivateKey(byte[] data, String key) throws Exception{		byte[] keyBytes = decryptBASE64(key);				//取得私钥		PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);		KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);		Key pKey = factory.generatePrivate(encodedKeySpec);				//对数据解密		Cipher cipher = Cipher.getInstance(factory.getAlgorithm());		cipher.init(Cipher.DECRYPT_MODE, pKey);				return cipher.doFinal(data);	}		/**	 * 用公钥解密	 * @param data	 * @param key	 * @return	 * @throws Exception	 */	public static byte[] decryptByPublicKey( byte[] data, String key) throws Exception{				//解密		byte[] keyBytes = decryptBASE64(key);				//取得公钥		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);		Key pKey = keyFactory.generatePublic(keySpec);				//对数据解密		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());		cipher.init(Cipher.DECRYPT_MODE, pKey);				return cipher.doFinal(data);	}		/**	 * 用公钥加密	 * @param data	 * @param key	 * @return	 * @throws Exception	 */	public static byte[] encryptByPublicKey( byte[] data, String key) throws Exception{				byte[] keyBytes = decryptBASE64(key);				X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);		Key pKey = keyFactory.generatePublic(keySpec);						Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());		cipher.init(Cipher.ENCRYPT_MODE, pKey);				return cipher.doFinal(data);	}		/**	 * 用私钥加密	 * @param data	 * @param key	 * @return	 * @throws Exception	 */	public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception{				byte[] keyBytes = decryptBASE64(key);				PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);		Key privateKey = keyFactory.generatePrivate(keySpec);				Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());		cipher.init(Cipher.ENCRYPT_MODE, privateKey);				return cipher.doFinal(data);	}		/**	 * 取得私钥	 * @param keyMap	 * @return	 * @throws Exception	 */	public static String getPrivateKey( Map<String, Object> keyMap) throws Exception{		Key key = (Key) keyMap.get(PRIVATE_KEY);				return encryptBASE64(key.getEncoded());	}		/**	 * 取得公钥	 * @param keyMap	 * @return	 * @throws Exception	 */	public static String getPublicKey( Map<String, Object> keyMap) throws Exception{		Key key = (Key) keyMap.get(PUBLIC_KEY);				return encryptBASE64(key.getEncoded());	}	/**	 * 初始化密钥	 * @return	 * @throws Exception	 */	public static Map<String, Object> initKey() throws Exception{				KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);		keyPairGenerator.initialize(1024);				KeyPair keyPair = keyPairGenerator.generateKeyPair();		//公钥		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();				//私钥		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();				Map<String, Object> keyMap = new HashMap<String, Object>(2);		keyMap.put(PRIVATE_KEY, privateKey);		keyMap.put(PUBLIC_KEY, publicKey);		return keyMap;	}}

  

package com.bank.test;import java.util.Map;import org.junit.Assert;import org.junit.Before;import org.junit.Test;import com.bank.utils.RSACoder;public class RSACoderTest {	private String publicKey;	private String privateKey;	/*	 * 非对称加密算法   RSA过程 : 以甲乙双方为例	 * 		1、初始化密钥 构建密钥对,生成公钥、私钥保存到keymap中	 * 				KeyPairGenerator --->	KeyPair		-->		RSAPublicKey、RSAPrivateKey	 * 		2、甲方使用私钥加密, 加密后在用私钥对加密数据进行数据签名,然后发送给乙方	 * 				RSACoder.encryptByPrivateKey(data, privateKey);	 * 				RSACoder.sign(encodedData, privateKey);	 * 		3、乙方则通过公钥验证签名的加密数据,如果验证正确则在通过公钥对加密数据进行解密	 * 				RSACoder.verify(encodedData, publicKey, sign);	 * 				RSACoder.decryptByPublicKey(encodedData, publicKey);					 * 	 * 		4、乙方在通过公钥加密发送给甲方	 * 				RSACoder.encryptByPublicKey(decodedData, publicKey);	 * 		5、甲方通过私钥解密该数据			 * 				RSACoder.decryptPrivateKey(encodedData, privateKey);					 */	@Before	public void setUp() throws Exception {				Map<String , Object> keyMap = RSACoder.initKey();				publicKey = RSACoder.getPublicKey(keyMap);		privateKey = RSACoder.getPrivateKey(keyMap);				System.out.println("公钥:\n" + publicKey);		System.out.println("私钥:\n" + privateKey);	}	@Test	public void test() throws Exception{		String inputStr = "abc";		byte[] data = http://www.mamicode.com/inputStr.getBytes();//每次的得到的字节数组是不一样的。"flag:" + flag);		//用公钥对数据解密		byte[] decodedData = http://www.mamicode.com/RSACoder.decryptByPublicKey(encodedData, publicKey);"data:" + data + "加密数据:" + encodedData + "    解密数据:" + decodedData);		System.out.println("加密前数据-:" + new String(data) + "     解密后数据: " + new String(decodedData));				//第四步使用公钥加密数据		encodedData = http://www.mamicode.com/RSACoder.encryptByPublicKey(decodedData, publicKey);"data:" + data + "加密数据:" + encodedData + "    解密数据:" + decodedData);		System.out.println("加密前数据:" + inputStr + "     解密后数据: " + new String(decodedData));	}			@Test	public void test1() throws Exception{		System.out.println("私钥加密-----公钥解密");		String inputStr = "abc";		byte[] data = http://www.mamicode.com/inputStr.getBytes();"data:" + data);				byte[] encodedData = http://www.mamicode.com/RSACoder.encryptByPrivateKey(data, privateKey);"加密前:" + inputStr +"\n 解密后:" + outputStr);				Assert.assertEquals(inputStr, outputStr);						System.out.println("私钥签名---公钥验证签名");		//产生签名		String sign = RSACoder.sign(encodedData, privateKey);		System.out.println("签名:\r" + sign);				//验证签名		boolean flag = RSACoder.verify(encodedData, publicKey, sign);				System.out.println("状态:\r" + flag);				Assert.assertTrue(flag);	}}

  

 

JAVA 非对称加密算法RSA