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);
	}
}

  

时间: 2024-10-05 05:31:20

JAVA 非对称加密算法RSA的相关文章

Java非对称加密算法--RSA加密算法

Java非对称加密算法--RSA加密算法          RSA加密算法是一种非对称加密算法.在公开密钥加密和电子商业中RSA被广泛使用.RSA是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院工作.RSA就是他们三人姓氏开头字母拼在一起组成的. 1973年,在英国政府通讯总部工作的数学家克利福德·柯克斯(Clifford Cocks)在一个内部文件中提出了一个相

Java加密技术(四)非对称加密算法RSA

RSA  这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法.它易于理解和操作,也很流行.算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman. 这种加密算法的特点主要是密钥的变化,上文我们看到DES只有一个密钥.相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了.RSA同时有两把钥匙,公钥与私钥.同时支持数字签名.数字签名的意义在于,对传输过来的数据进行校验.确保数据在传输工程中不被修改. 流程分析: 甲方构建

非对称加密算法RSA使用注意事项

原文:非对称加密算法RSA使用注意事项 第一个问题,也是最重要的一个——RSA无法对超过117字节的数据进行加密!切记!其实也勿需要求对更大数据的加密,虽然网上已经有相关解决方案,比如BigInteger项目.但这点确实需要注意,如果对大于117字节的数据加密就会抛异常出来,说法还有点莫名其妙.考虑下RSA的主要用途就可以理解了,一般我们使用RSA的主要用途是进行数字签名,另外就是对“对称加密”算法的KEY和IV向量进行加密: 第二个问题,假设要对一个文本文件(比如xml文件)中的某些数据进行加

第十二章 非对称加密算法-RSA

注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第8章“高等加密算法--非对称加密算法” 12.1.RSA(最经典的非对称加密算法) 特点: 使用一套密钥即可完成加解密(与DH不同) 与DH不同的第二点是,RSA自己可以完成加解密,而DH需要依赖于对称加密算法 “私钥加密,公钥解密”或“公钥加密,私钥解密” 公钥长度远小于私钥长度(对下边的代码进行测试,自己比较结果) 加解密流程: 1)发送方(假设为甲方)构建密钥对,自己保留私钥,将公钥发送给接收方(假设为乙方) 2)甲方使用密

openssl 非对称加密算法RSA命令详解

1.非对称加密算法概述 非对称加密算法也称公开密钥算法,其解决了对称加密算法密钥分配的问题,非对称加密算法基本特点如下: 1.加密密钥和解密密钥不同 2.密钥对中的一个密钥可以公开 3.根据公开密钥很难推算出私人密钥 根据非对称加密算法的特点,可用户数字签名.密钥交换.数据加密.但是由于非对称加密算法较对称加密算法加密速度慢很多,故最常用的用途是数字签名和密钥交换. 目前常用的非对称加密算法有RSA, DH和DSA三种,但并非都可以用于密钥交换和数字签名.而是RSA可用于数字签名和密钥交换,DH

信息加密之非对称加密算法RSA

前面为大家已经总结了,基于密钥交换的DH算法,现在就为大家再介绍一种基于因子分解的RSA算法,这种加密算法有两种实现形式:1.公钥加密,私钥解密:2.私钥加密,公钥解密.下面就为大家分析一下实现代码,相对于DH算法,RSA显得有些简单.初始化密钥: KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(512); KeyPair keyPa

非对称加密算法RSA

RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年首次公布,当时他们三人都在麻省理工学院工作.RSA就是他们三人姓氏开头字母拼在一起组成的. RSA算法晚于DH算法,这五个字母全都是人名首字母.DH算法是第一个非对称密码体系. RSA算法运算速度慢,不适宜加密大量数据.一种解决方案是,将RSA跟对称加密方式混合使用,将数据使用对称加密方式加密,对称加密的密钥使用RS

非对称加密算法-RSA算法

??加密算法分为对称加密算法和非对称加密算法,其中非对称加密算法作为计算机通信安全的基石,在保证数据安全方面起着重要的作用.而相对于对称加密算法的易理解性,非对称加密算法存在一定的难度.下面通过对RSA算法的剖析,让我们更好的理解非对称加密算法的原理. 一.对称加密算法和非对称加密算法 1.对称加密算法 ??对称加密算法:加密和解密都使用同样规则(密钥)的算法. ??(1).A选择某一种规则对信息进行加密: ??(2).B使用同一规则(逆规则)对信息进行解密: 2.非对称加密算法 ??非对称加密

java 非对称加密RSA

package com.aarony.test; import java.io.IOException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.sec