DSA-Digital Signature Algorithm(Schnorr和ElGamal签名算法的变种)
2012-01-29 13:54
465 查看
package com.ice.webos.util.security; 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-Digital Signature Algorithm * 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。<br> * 简单的说,这是一种更高级的验证方式,用作数字签名。<br> * 不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。<br> * 如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。<br> * 数字签名,是单向加密的升级! * * @author Ice_Liu * */ public class DSACryptUtil { public static final String ALGORITHM = "DSA"; /** * 默认密钥字节数 * * <pre> * * DSA * Default Keysize 1024 * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive). * </pre> */ private static final int KEY_SIZE = 1024; /** * 默认种子 */ private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3"; private static final String PUBLIC_KEY = "DSAPublicKey"; private static final String PRIVATE_KEY = "DSAPrivateKey"; /** * 用私钥对信息生成数字签名 * * @param data * 加密数据 * @param privateKey * 私钥 * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { // 解密由base64编码的私钥 byte[] keyBytes = CryptUtil.decryptBASE64(privateKey); // 构造PKCS8EncodedKeySpec对象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); // 取私钥匙对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私钥对信息生成数字签名 Signature signature = Signature.getInstance(keyFactory.getAlgorithm()); signature.initSign(priKey); signature.update(data); return CryptUtil.encryptBASE64(signature.sign()); } /** * 校验数字签名 * * @param data * 加密数据 * @param publicKey * 公钥 * @param sign * 数字签名 * * @return 校验成功返回true 失败返回false * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解密由base64编码的公钥 byte[] keyBytes = CryptUtil.decryptBASE64(publicKey); // 构造X509EncodedKeySpec对象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); // 取公钥匙对象 PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(keyFactory.getAlgorithm()); signature.initVerify(pubKey); signature.update(data); // 验证签名是否正常 return signature.verify(CryptUtil.decryptBASE64(sign)); } /** * 生成密钥 * * @param seed * 种子 * @return 密钥对象 * @throws Exception */ public static Map<String, Object> initKey(String seed) throws Exception { KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM); // 初始化随机产生器 SecureRandom secureRandom = new SecureRandom(); secureRandom.setSeed(seed.getBytes()); keygen.initialize(KEY_SIZE, 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; } /** * 默认生成密钥 * * @return 密钥对象 * @throws Exception */ public static Map<String, Object> initKey() throws Exception { return initKey(DEFAULT_SEED); } /** * 取得私钥 * * @param keyMap * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return CryptUtil.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 CryptUtil.encryptBASE64(key.getEncoded()); } public static void main(String[] args) { try { DHCryptUtil.main(args); System.out.println("************************************"); System.out.println("DSA 加密与解密"); String inputStr = "abc"; byte[] data = inputStr.getBytes(); // 构建密钥 Map<String, Object> keyMap = DSACryptUtil.initKey(); // 获得密钥 String publicKey = DSACryptUtil.getPublicKey(keyMap); String privateKey = DSACryptUtil.getPrivateKey(keyMap); System.err.println("公钥:\r" + publicKey); System.err.println("私钥:\r" + privateKey); // 产生签名 String sign = DSACryptUtil.sign(data, privateKey); System.err.println("签名:\r" + sign); // 验证签名 boolean status = DSACryptUtil.verify(data, publicKey, sign); System.err.println("状态:\r" + status); } catch (Exception e) { e.printStackTrace(); } } }
相关文章推荐
- 数据签名标准算法-DSA (Digital signature Algorithm DSA)
- 第四十八篇:JAVA加密解密之DSA(Digital Signature Algorithm)算法
- JAVA加密解密之DSA(Digital Signature Algorithm)算法
- Digital Signature Algorithm(DSA)
- Bitcoin学习篇之---Elliptic Curve Digital Signature Algorithm(椭圆曲线数字签名算法)
- ElGamal公钥密码算法及ElGamal数字签名方案实现
- 错误:文件被数字签名策略拒绝(File was rejected by digital signature policy)
- ECDSA (Elliptic Curve Digital Signature Algorithm)
- 文件被数字签名策略拒绝(File was rejected by digital signature policy)
- 文件被数字签名策略拒绝(File was rejected by digital signature policy)
- 文件被数字签名策略拒绝(File was rejected by digital signature policy)
- 文件被数字签名策略拒绝(File was rejected by digital signature policy)
- 各种加密签名算法MD5/SHA, DES,RSA,DSA,ECC
- 签名signature算法没错导致invalid signature和permission denied原因
- the third-party inf does not contain digital signature information,win8安装自己的驱动,忽略数字签名的问题
- 文件被数字签名策略拒绝(File was rejected by digital signature policy)
- 数据加密:什么是数据签名(What is a Digital Signature?)
- 错误:文件被数字签名策略拒绝(File was rejected by digital signature policy)
- rejected by digital signature policy 数字签名策略拒绝
- 文件被数字签名策略拒绝(File was rejected by digital signature policy)