DSA 实现
/*** -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);// 实例化SignatureSignature signature = Signature.getInstance(SIGNATURE_ALGORITHM);// 初始化Signaturesignature.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);// 实例话SignatureSignature signature = Signature.getInstance(SIGNATURE_ALGORITHM);// 初始化Signaturesignature.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 示例
/*** -5-7*/package org.zlex.chapter09_2;import static org.junit.Assert.*;import java.util.Map;import mons.codec.binary.Base64;import mons.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*/@Beforepublic 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*/@Testpublic 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);}}