RSA 实现
/**
* 2008-6-11
*/
package org.zlex.chapter09_1;
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;
/**
* RSA安全编码组件
*
* @author 梁栋
* @version 1.0
*/
public abstract class RSACoder {
/**
* 数字签名
* 密钥算法
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 数字签名
* 签名/验证算法
*/
public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
/**
* 公钥
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/**
* 私钥
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* RSA密钥长度 默认1024位,
* 密钥长度必须是64的倍数,
* 范围在512至65536位之间。
*/
private static final int KEY_SIZE = 512;
/**
* 签名
*
* @param data
* 待签名数据
* @param privateKey
* 私钥
* @return byte[] 数字签名
* @throws Exception
*/
public static byte[] sign(byte[] data, byte[] privateKey) throws Exception {
// 转换私钥材料
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
// 实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取私钥匙对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 实例化Signature
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
// 初始化Signature
signature.initSign(priKey);
// 更新
signature.update(data);
// 签名
return signature.sign();
}
/**
* 校验
*
* @param data
* 待校验数据
* @param publicKey
* 公钥
* @param sign
* 数字签名
*
* @return boolean 校验成功返回true 失败返回false
* @throws Exception
*
*/
public static boolean verify(byte[] data, byte[] publicKey, byte[] sign)
throws Exception {
// 转换公钥材料
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
// 实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成公钥
PublicKey pubKey = keyFactory.generatePublic(keySpec);
// 实例化Signature
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
// 初始化Signature
signature.initVerify(pubKey);
// 更新
signature.update(data);
// 验证
return signature.verify(sign);
}
/**
* 取得私钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static byte[] getPrivateKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key.getEncoded();
}
/**
* 取得公钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static byte[] getPublicKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
/**
* 初始化密钥
*
* @return Map 密钥对儿 Map
* @throws Exception
*/
public static Map<String, Object> 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<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
}
RSA 示例
/**
* 2008-6-11
*/
package org.zlex.chapter09_1;
import static org.junit.Assert.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.junit.Before;
import org.junit.Test;
import java.util.Map;
/**
* RSA数字签名校验
*
* @author 梁栋
* @version 1.0
*/
public class RSACoderTest {
/**
* 公钥
*/
private byte[] publicKey;
/**
* 私钥
*/
private byte[] privateKey;
/**
* 初始化密钥
*
* @throws Exception
*/
@Before
public void initKey() throws Exception {
Map<String, Object> keyMap = RSACoder.initKey();
publicKey = RSACoder.getPublicKey(keyMap);
privateKey = RSACoder.getPrivateKey(keyMap);
System.err.println("公钥: \n" + Base64.encodeBase64String(publicKey));
System.err.println("私钥: \n" + Base64.encodeBase64String(privateKey));
}
/**
* 校验
*
* @throws Exception
*/
@Test
public void testSign() throws Exception {
String inputStr = "RSA数字签名";
byte[] data = inputStr.getBytes();
// 产生签名
byte[] sign = RSACoder.sign(data, privateKey);
System.err.println("签名:\n" + Hex.encodeHexString(sign));
// 验证签名
boolean status = RSACoder.verify(data, publicKey, sign);
System.err.println("状态:\n" + status);
assertTrue(status);
}
}