RSA加密算法

        RSA公钥加密算法是1977年由RonRivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

         SET(Secure Electronic Transaction)协议中要求CA采用2048bits长的密钥,其他实体使用1024比特的密钥。RSA密钥长度随着保密级别提高,增加很快。下表xxx列出了对同一安全级别所对应的密钥长度。

             表xxx    同一安全级别所对应的密钥长度

保密级别

对称密钥长度(bit)

RSA密钥长度(bit)

ECC密钥长度(bit)

保密年限

80

80

1024

160

2010

112

112

2048

224

2030

128

128

3072

256

2040

192

192

7680

384

2080

256

256

15360

512

2120


            有关于RSA算法实现Java 6实现与Bouncy Castle实现细节如下表xxx所示:

 

                   表xxx      RSA算法

算法

密钥长度

默认密钥长度

工作模式

填充方式

备注

RSA

512~65536位

(密钥必须

是64的倍数)

1024

ECB

NoPadding、PKCS1Padding、

OAEPWITHMD5AndMGF1Padding、

OAEPWITHSHA1AndMGF1Padding、

OAEPWITHSHA256AndMGF1Padding、

OAEPWITHSHA384AndMGF1Padding、

OAEPWITHSHA512AndMGF1Padding

Java6实现

2048

NONE

NoPadding、PKCS1Padding、

OAEPWITHMD5AndMGF1Padding、

OAEPWITHSHA1AndMGF1Padding、

OAEPWITHSHA256AndMGF1Padding、

OAEPWITHSHA384AndMGF1Padding、

OAEPWITHSHA512AndMGF1Padding、

ISO9796-1Padding

bouncy castle实现

主要代码如下:


RSECoder.java

/*
 * Copyright 2013 WeCode authors
 * 
 *  Licensed under the WeCode, Version 1.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License from [email protected]
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.wecode.security.algorithes;

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.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;

import org.apache.commons.codec.binary.Hex;

/**
 * RSA加密组件
 * 
 * @author ydonghao2
 * @version 2.0
 */

public abstract class RSACoder {
	// 非对称加密算法
	public static final String KEY_ALGORITHM = "RSA";
	// 公钥
	private static final String PUBLIC_KEY = "RSAPublicKey";
	// 私钥
	private static final String PRIVATE_KEY = "RSAPrivateKey";
	// RSA密钥长度 2048
	private static final int KEY_SIZE = 2048;

	/**
	 * 私钥解密
	 * 
	 * @param data
	 *            待解密 数据
	 * @param key
	 *            私钥
	 * @return byte[] 解密数据
	 * @throws Exception
	 */
	public static byte[] decryptByPrivateKey(byte[] data, byte[] key)
			throws Exception {
		// 取得私钥
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		// 生成私钥
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
		// 对数据解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		return cipher.doFinal(data);
	}

	/**
	 * 公钥解密
	 * 
	 * @param data
	 *            待解密数据
	 * @param key
	 *            公钥
	 * @return byte[] 解密数据
	 * @throws Exception
	 */
	public static byte[] decryptByPublicKey(byte[] data, byte[] key)
			throws Exception {
		// 取得公钥
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		// 生成公钥
		PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
		// 对数据解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, publicKey);
		return cipher.doFinal(data);
	}

	/**
	 * 公钥加密
	 * 
	 * @param data
	 *            待加密数据
	 * @param key
	 *            公钥
	 * @return byte[] 加密数据
	 * @throws Exception
	 */
	public static byte[] encryptByPublicKey(byte[] data, byte[] key)
			throws Exception {
		// 取得公钥
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
		// 对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		return cipher.doFinal(data);
	}

	/**
	 * 私钥加密
	 * 
	 * @param data
	 *            待加密 数据
	 * @param key
	 *            私钥
	 * @return byte[] 加密数据
	 * @throws Exception
	 */
	public static byte[] encryptByPrivateKey(byte[] data, byte[] key)
			throws Exception {
		// 取得私钥
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		// 生成私钥
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
		// 对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
		return cipher.doFinal(data);
	}

	/**
	 * 取得私钥
	 * 
	 * @param keyMap
	 *            密钥Map
	 * @return byte[] 私钥
	 * @throws Exception
	 */
	public static byte[] getPrivateKey(Map keyMap)
			throws Exception {
		Key key = (Key) keyMap.get(PRIVATE_KEY);
		return key.getEncoded();
	}

	/**
	 * 取得公钥
	 * 
	 * @param keyMap
	 *            密钥Map
	 * @return byte[] 私钥
	 * @throws Exception
	 */
	public static byte[] getPublicKey(Map keyMap)
			throws Exception {
		Key key = (Key) keyMap.get(PUBLIC_KEY);
		return key.getEncoded();
	}

	/**
	 * 初始化密钥
	 * 
	 * @return 密钥Map
	 * @throws Exception
	 */
	public static Map initKey() throws Exception {
		// 实例化密钥对生成器
		KeyPairGenerator keyPairGen = KeyPairGenerator
				.getInstance(KEY_ALGORITHM);
		// 初始化密钥对的生成
		keyPairGen.initialize(KEY_SIZE);
		// 生成密钥对
		KeyPair keyPair = keyPairGen.generateKeyPair();
		// 公钥
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
		// 私钥
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
		// 封装密钥
		Map keyMap = new HashMap(2);
		keyMap.put(PUBLIC_KEY, publicKey);
		keyMap.put(PRIVATE_KEY, privateKey);
		return keyMap;
	}

	/**
	 * 私钥解密
	 * 
	 * @param data
	 *            待解密 数据
	 * @param key
	 *            私钥
	 * @return byte[] 解密数据
	 * @throws Exception
	 */
	public static byte[] encryByPrivateKey(byte[] data, String key)
			throws Exception {
		return encryptByPrivateKey(data, getKey(key));
	}

	/**
	 * 公钥加密
	 * 
	 * @param data
	 *            待加密数据
	 * @param key
	 *            公钥
	 * @return byte[] 加密数据
	 * @throws Exception
	 */
	public static byte[] encryptByPublicKey(byte[] data, String key)
			throws Exception {
		return encryptByPublicKey(data, getKey(key));
	}

	/**
	 * 私钥解密
	 * 
	 * @param data
	 *            待解密 数据
	 * @param key
	 *            私钥
	 * @return byte[] 解密数据
	 * @throws Exception
	 */
	public static byte[] decryptByPrivateKey(byte[] data, String key)
			throws Exception {
		return decryptByPrivateKey(data, getKey(key));
	}

	/**
	 * 公钥解密
	 * 
	 * @param data
	 *            待解密数据
	 * @param key
	 *            公钥
	 * @return byte[] 解密数据
	 * @throws Exception
	 */
	public static byte[] decryptByPublicKey(byte[] data, String key)
			throws Exception {
		return decryptByPublicKey(data, getKey(key));
	}
	
	/**
	 * 初始化密钥
	 * @param 密钥Map
	 * @return String 16进制编码密钥
	 * @throws Exception
	 */
	public static String getPrivateKeyString(Map keyMap) throws Exception {
		return Hex.encodeHexString(getPrivateKey(keyMap));
	}
	/**
	 * 初始化密钥
	 * @param 密钥Map
	 * @return String 16进制编码密钥
	 * @throws Exception
	 */
	public static String getPublicKeyString(Map keyMap) throws Exception {
		return Hex.encodeHexString(getPublicKey(keyMap));
	}
	
	public static byte[] getKey(String key) throws Exception {
		return Hex.decodeHex(key.toCharArray());
	}
}


KEY_ALGORITHM指明非对称加密算法“RSA”;PUBLIC_KEY指明非对称算法的公钥,私钥指明非对称算法的私钥。

public static finalString KEY_ALGORITHM = "RSA";
private static finalString PUBLIC_KEY = "RSAPublicKey";
private static finalString PRIVATE_KEY = "RSAPrivateKey";

KEY_SIZE指明本系统此处RSA密钥长度为2048

private static final intKEY_SIZE = 2048;

私钥解密

参数:

        data - 待解密 数据

         key - 私钥

返回:

        byte[] 解密数据

抛出:

        java.lang.Exception

        PKCS8EncodedKeySpec pkcs8KeySpec = newPKCS8EncodedKeySpec(key);用于取得私钥。 PKCS8EncodedKeySpec类用于转换私钥编码。它继承EncodedKeySpec类,以编码格式表示私钥。PKCS8EncodedKeySpec类使用PKCS#8标准展位密钥规范管理的编码格式。

public static byte[]decryptByPrivateKey(byte[] data, byte[] key)
        throws Exception {
    PKCS8EncodedKeySpecpkcs8KeySpec = new PKCS8EncodedKeySpec(key);
    KeyFactory keyFactory= KeyFactory.getInstance(KEY_ALGORITHM);
    // 生成私钥
    PrivateKey privateKey= keyFactory.generatePrivate(pkcs8KeySpec);
    // 对数据解密
    Cipher cipher =Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE,privateKey);
    returncipher.doFinal(data);
}

私钥解密

参数:

        data - 待解密 数据

        key - 私钥

返回:

        byte[] 解密数据

抛出:

        java.lang.Exception

public static byte[] decryptByPrivateKey(byte[] data,

                        java.lang.String key)  throwsjava.lang.Exception

公钥解密

参数:

         data - 待解密数据

         key - 公钥

返回:

         byte[] 解密数据

抛出:

        java.lang.Exception

X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);用于取得公钥。X509EncodedKeySpec类使用X.509标准作为密钥规范的编码格式。通过如下方法实例化:

public X509EncodedKeySpec(byte[] encodedKey)

根据给定的编码密钥创建一个新的 X509EncodedKeySpec。

public static byte[]decryptByPublicKey(byte[] data, byte[] key)
        throws Exception {
    X509EncodedKeySpecx509KeySpec = new X509EncodedKeySpec(key);
    KeyFactory keyFactory= KeyFactory.getInstance(KEY_ALGORITHM);
    // 生成公钥
    PublicKey publicKey =keyFactory.generatePublic(x509KeySpec);
    // 对数据解密
    Cipher cipher =Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE,publicKey);
    returncipher.doFinal(data);
}

公钥解密

参数:

       data - 待解密数据

       key - 公钥

返回:

        byte[] 解密数据

抛出:

      java.lang.Exception 

  • public static byte[] decryptByPublicKey(byte[] data,

         java.lang.String key)  throws java.lang.Exception

公钥加密

参数:

       data - 待加密数据

       key - 公钥

返回:

       byte[] 加密数据

抛出:

       java.lang.Exception

      KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);获得实例化对象。KeyFactory类也是用来生成密钥(公钥和私钥)的引擎类。用于产生公钥/私钥,或者说它的作用是通过密钥规范还原密钥。

public static byte[]encryptByPublicKey(byte[] data, byte[] key)
        throws Exception {
    // 取得公钥
    X509EncodedKeySpecx509KeySpec = new X509EncodedKeySpec(key);
    KeyFactory keyFactory= KeyFactory.getInstance(KEY_ALGORITHM);
    PublicKey publicKey =keyFactory.generatePublic(x509KeySpec);
    // 对数据加密
    Cipher cipher =Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE,publicKey);
    returncipher.doFinal(data);
}


公钥加密

参数:

        data - 待加密数据

        key - 公钥

返回:

        byte[] 加密数据

抛出:

       java.lang.Exception

  • public static byte[] encryptByPublicKey(byte[] data,java.lang.String key)

                                throws java.lang.Exception

  • public static byte[] encryptByPrivateKey(byte[] data,byte[] key)

                                  throwsjava.lang.Exception

私钥加密

参数:

        data - 待加密 数据

        key - 私钥

返回:

        byte[] 加密数据

抛出:

java.lang.Exception

public static byte[]encryptByPrivateKey(byte[] data, byte[] key)
        throws Exception {
    // 取得私钥
    PKCS8EncodedKeySpecpkcs8KeySpec = new PKCS8EncodedKeySpec(key);
    KeyFactory keyFactory= KeyFactory.getInstance(KEY_ALGORITHM);
    // 生成私钥
    PrivateKey privateKey= keyFactory.generatePrivate(pkcs8KeySpec);
    // 对数据加密
    Cipher cipher =Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE,privateKey);
    returncipher.doFinal(data);
}

初始化密钥

返回:

        密钥Map

抛出:

        java.lang.Exception

        KeyPairGenerator是个抽象类。公钥和私钥的生成是由KeyPairGenerator类来实现的。KeyPairGenerator也是通过getInstance()方法来实现实例化的。

public staticMap initKey() throws Exception {
    // 实例化密钥对生成器
    KeyPairGeneratorkeyPairGen = KeyPairGenerator
           .getInstance(KEY_ALGORITHM);
    // 初始化密钥对的生成
    keyPairGen.initialize(KEY_SIZE);
    // 生成密钥对
    KeyPair keyPair =keyPairGen.generateKeyPair();
    // 公钥
    RSAPublicKey publicKey= (RSAPublicKey) keyPair.getPublic();
    // 私钥
    RSAPrivateKeyprivateKey = (RSAPrivateKey) keyPair.getPrivate();
    // 封装密钥
    Map keyMap = new HashMap(2);
    keyMap.put(PUBLIC_KEY,publicKey);
    keyMap.put(PRIVATE_KEY,privateKey);
    return keyMap;
}


测试RSACoder.java:
RSAcoderTest.java

package com.wecode.security.algorithes;

import static org.junit.Assert.*;

import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.junit.Before;
import org.junit.Test;

/**
 * RSA校验
 * 
 * @author ydonghao2
 * 
 */

public class RSACoderTest {
	// 公钥
	private static byte[] publicKey;
	// 私钥
	private static byte[] privateKey;

	/**
	 * 初始化密钥
	 */
	
	/**
	 * 测试的时候把@Before,@Test去掉
	 * 把:private byte[] publicKey;
	 * 改成:private static byte[] publicKey;
	 * 把:private byte[] privateKey;
	 * 改成:private static byte[] privateKey;
	 * 把:public void initKey() throws Exception {
	 * 改成:public void static initKey() throws Exception {
	 * 把:public void test() throws Exception {
	 * 改成:改成:public static void main(String[] args) throws Exception {
	 * 在main函数中加入:initKey();
	 * @return 
	 * @throws Exception
	 */
	//@Before
	 public static void initKey() throws Exception {
		// 初始化密钥
		Map keyMap = RSACoder.initKey();
		publicKey = RSACoder.getPublicKey(keyMap);
		privateKey = RSACoder.getPrivateKey(keyMap);
		System.err.println("公钥:\t" + Base64.encodeBase64String(publicKey));
		System.err.println("公钥:\t" + publicKey.toString());
		System.err.println("私钥:\t" + Base64.encodeBase64String(privateKey));
		System.err.println("公钥:\t" + privateKey.toString());
	}

	/**
	 * 校验
	 * 
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		initKey();
		System.err.println("---私钥加密----公钥解密----");
		String inputStr1 = "RSA";
		byte[] data1 = inputStr1.getBytes();
		System.err.println("原文:\t" + inputStr1);
		// 加密
		byte[] encodedData1 = RSACoder.encryptByPrivateKey(data1, privateKey);
		System.err.println("加密后:\t" + Base64.encodeBase64String(encodedData1));
		// 解密
		byte[] decodedData1 = RSACoder.decryptByPublicKey(encodedData1,
				publicKey);
		String outputStr1 = new String(decodedData1);
		System.err.println("解密后:\t" + outputStr1);

		// 校验
		assertEquals(inputStr1, outputStr1);
	}

}


你可能感兴趣的:(信息安全)