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 = inputStr.getBytes();//每次的得到的字节数组是不一样的。

		//第二步 私钥加密

		byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);

		//私钥进行数据签名

		String sign = RSACoder.sign(encodedData, privateKey);

		

		//第三步 公钥验证数字签名

		boolean flag = RSACoder.verify(encodedData, publicKey, sign);

		System.out.println("flag:" + flag);

		//用公钥对数据解密

		byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);

		

		System.out.println("data:" + data + "加密数据:" + encodedData + "    解密数据:" + decodedData);

		System.out.println("加密前数据-:" + new String(data) + "     解密后数据: " + new String(decodedData));

		

		//第四步使用公钥加密数据

		encodedData = RSACoder.encryptByPublicKey(decodedData, publicKey);

		

		//第五步 使用私钥解密数据

		decodedData = RSACoder.decryptPrivateKey(encodedData, privateKey);

		

		

		System.out.println("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 = inputStr.getBytes();

		System.out.println("data:" + data);

		

		byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);

		byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);

	

		String outputStr = new String( decodedData );

		

		System.out.println("加密前:" + 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);

	}

}

  

 

你可能感兴趣的:(非对称加密算法)