DSA 实现
/**
* 2008-6-13
*/
package org.zlex.chapter09_2;
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.SecureRandom;
import java.security.Signature;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
* DSA安全编码组件
*
* @author 梁栋
* @version 1.0
*/
public abstract class DSACoder {
/**
* 数字签名密钥算法
*/
public static final String ALGORITHM = "DSA";
/**
* 数字签名
* 签名/验证算法
*/
public static final String SIGNATURE_ALGORITHM = "SHA1withDSA";
/**
* 公钥
*/
private static final String PUBLIC_KEY = "DSAPublicKey";
/**
* 私钥
*/
private static final String PRIVATE_KEY = "DSAPrivateKey";
/**
* DSA密钥长度
* 默认1024位,
* 密钥长度必须是64的倍数,
* 范围在512至1024位之间(含)
*/
private static final int KEY_SIZE = 1024;
/**
* 签名
*
* @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(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(ALGORITHM);
// 取公钥匙对象
PublicKey pubKey = keyFactory.generatePublic(keySpec);
// 实例话Signature
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
// 初始化Signature
signature.initVerify(pubKey);
// 更新
signature.update(data);
// 验证
return signature.verify(sign);
}
/**
* 生成密钥
*
* @return 密钥对象
* @throws Exception
*/
public static Map<String, Object> initKey() throws Exception {
// 初始化密钥对儿生成器
KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM);
// 实例化密钥对儿生成器
keygen.initialize(KEY_SIZE, new SecureRandom());
// 实例化密钥对儿
KeyPair keys = keygen.genKeyPair();
DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic();
DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate();
// 封装密钥
Map<String, Object> map = new HashMap<String, Object>(2);
map.put(PUBLIC_KEY, publicKey);
map.put(PRIVATE_KEY, privateKey);
return map;
}
/**
* 取得私钥
*
* @param keyMap
* 密钥Map
* @return byte[] 私钥
* @throws Exception
*/
public static byte[] getPrivateKey(Map<String, Object> 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<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
}
DSA 示例
/**
* 2009-5-7
*/
package org.zlex.chapter09_2;
import static org.junit.Assert.*;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.junit.Before;
import org.junit.Test;
/**
* DSA签名校验
*
* @author 梁栋
* @version 1.0
*/
public class DSACoderTest {
/**
* 公钥
*/
private byte[] publicKey;
/**
* 私钥
*/
private byte[] privateKey;
/**
* 初始化密钥
*
* @throws Exception
*/
@Before
public void initKey() throws Exception {
Map<String, Object> keyMap = DSACoder.initKey();
publicKey = DSACoder.getPublicKey(keyMap);
privateKey = DSACoder.getPrivateKey(keyMap);
System.err.println("公钥: \n" + Base64.encodeBase64String(publicKey));
System.err.println("私钥: \n" + Base64.encodeBase64String(privateKey));
}
/**
* 校验签名
*
* @throws Exception
*/
@Test
public void test() throws Exception {
String inputStr = "DSA数字签名";
byte[] data = inputStr.getBytes();
// 产生签名
byte[] sign = DSACoder.sign(data, privateKey);
System.err.println("签名:\r" + Hex.encodeHexString(sign));
// 验证签名
boolean status = DSACoder.verify(data, publicKey, sign);
System.err.println("状态:\r" + status);
assertTrue(status);
}
}