• DSADigital Signature Algorithm(Schnorr和ElGamal签名算法的变种)


      1 package com.ice.webos.util.security;
    2
    3 import java.security.Key;
    4 import java.security.KeyFactory;
    5 import java.security.KeyPair;
    6 import java.security.KeyPairGenerator;
    7 import java.security.PrivateKey;
    8 import java.security.PublicKey;
    9 import java.security.SecureRandom;
    10 import java.security.Signature;
    11 import java.security.interfaces.DSAPrivateKey;
    12 import java.security.interfaces.DSAPublicKey;
    13 import java.security.spec.PKCS8EncodedKeySpec;
    14 import java.security.spec.X509EncodedKeySpec;
    15 import java.util.HashMap;
    16 import java.util.Map;
    17
    18 /**
    19 * DSA-Digital Signature Algorithm
    20 * 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。<br>
    21 * 简单的说,这是一种更高级的验证方式,用作数字签名。<br>
    22 * 不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。<br>
    23 * 如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。<br>
    24 * 数字签名,是单向加密的升级!
    25 *
    26 * @author Ice_Liu
    27 *
    28 */
    29 public class DSACryptUtil {
    30
    31 public static final String ALGORITHM = "DSA";
    32
    33 /**
    34 * 默认密钥字节数
    35 *
    36 * <pre>
    37 *
    38 * DSA
    39 * Default Keysize 1024
    40 * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive).
    41 * </pre>
    42 */
    43 private static final int KEY_SIZE = 1024;
    44
    45 /**
    46 * 默认种子
    47 */
    48 private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3";
    49
    50 private static final String PUBLIC_KEY = "DSAPublicKey";
    51 private static final String PRIVATE_KEY = "DSAPrivateKey";
    52
    53 /**
    54 * 用私钥对信息生成数字签名
    55 *
    56 * @param data
    57 * 加密数据
    58 * @param privateKey
    59 * 私钥
    60 *
    61 * @return
    62 * @throws Exception
    63 */
    64 public static String sign(byte[] data, String privateKey) throws Exception {
    65 // 解密由base64编码的私钥
    66 byte[] keyBytes = CryptUtil.decryptBASE64(privateKey);
    67
    68 // 构造PKCS8EncodedKeySpec对象
    69 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    70
    71 // KEY_ALGORITHM 指定的加密算法
    72 KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    73
    74 // 取私钥匙对象
    75 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
    76
    77 // 用私钥对信息生成数字签名
    78 Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
    79 signature.initSign(priKey);
    80 signature.update(data);
    81
    82 return CryptUtil.encryptBASE64(signature.sign());
    83 }
    84
    85 /**
    86 * 校验数字签名
    87 *
    88 * @param data
    89 * 加密数据
    90 * @param publicKey
    91 * 公钥
    92 * @param sign
    93 * 数字签名
    94 *
    95 * @return 校验成功返回true 失败返回false
    96 * @throws Exception
    97 *
    98 */
    99 public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
    100
    101 // 解密由base64编码的公钥
    102 byte[] keyBytes = CryptUtil.decryptBASE64(publicKey);
    103
    104 // 构造X509EncodedKeySpec对象
    105 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    106
    107 // ALGORITHM 指定的加密算法
    108 KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    109
    110 // 取公钥匙对象
    111 PublicKey pubKey = keyFactory.generatePublic(keySpec);
    112
    113 Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
    114 signature.initVerify(pubKey);
    115 signature.update(data);
    116
    117 // 验证签名是否正常
    118 return signature.verify(CryptUtil.decryptBASE64(sign));
    119 }
    120
    121 /**
    122 * 生成密钥
    123 *
    124 * @param seed
    125 * 种子
    126 * @return 密钥对象
    127 * @throws Exception
    128 */
    129 public static Map<String, Object> initKey(String seed) throws Exception {
    130 KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM);
    131 // 初始化随机产生器
    132 SecureRandom secureRandom = new SecureRandom();
    133 secureRandom.setSeed(seed.getBytes());
    134 keygen.initialize(KEY_SIZE, secureRandom);
    135
    136 KeyPair keys = keygen.genKeyPair();
    137
    138 DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic();
    139 DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate();
    140
    141 Map<String, Object> map = new HashMap<String, Object>(2);
    142 map.put(PUBLIC_KEY, publicKey);
    143 map.put(PRIVATE_KEY, privateKey);
    144
    145 return map;
    146 }
    147
    148 /**
    149 * 默认生成密钥
    150 *
    151 * @return 密钥对象
    152 * @throws Exception
    153 */
    154 public static Map<String, Object> initKey() throws Exception {
    155 return initKey(DEFAULT_SEED);
    156 }
    157
    158 /**
    159 * 取得私钥
    160 *
    161 * @param keyMap
    162 * @return
    163 * @throws Exception
    164 */
    165 public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
    166 Key key = (Key) keyMap.get(PRIVATE_KEY);
    167
    168 return CryptUtil.encryptBASE64(key.getEncoded());
    169 }
    170
    171 /**
    172 * 取得公钥
    173 *
    174 * @param keyMap
    175 * @return
    176 * @throws Exception
    177 */
    178 public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
    179 Key key = (Key) keyMap.get(PUBLIC_KEY);
    180
    181 return CryptUtil.encryptBASE64(key.getEncoded());
    182 }
    183
    184 public static void main(String[] args) {
    185 try {
    186 DHCryptUtil.main(args);
    187 System.out.println("************************************");
    188 System.out.println("DSA 加密与解密");
    189 String inputStr = "abc";
    190 byte[] data = inputStr.getBytes();
    191
    192 // 构建密钥
    193 Map<String, Object> keyMap = DSACryptUtil.initKey();
    194 // 获得密钥
    195 String publicKey = DSACryptUtil.getPublicKey(keyMap);
    196 String privateKey = DSACryptUtil.getPrivateKey(keyMap);
    197
    198 System.err.println("公钥:\r" + publicKey);
    199 System.err.println("私钥:\r" + privateKey);
    200
    201 // 产生签名
    202 String sign = DSACryptUtil.sign(data, privateKey);
    203 System.err.println("签名:\r" + sign);
    204
    205 // 验证签名
    206 boolean status = DSACryptUtil.verify(data, publicKey, sign);
    207 System.err.println("状态:\r" + status);
    208
    209 } catch (Exception e) {
    210 e.printStackTrace();
    211 }
    212
    213 }
    214
    215 }
  • 相关阅读:
    HTML5学习笔记-2.HTML基础
    HTML5学习笔记-1.网页入门
    Java学习笔记-8.多线程编程
    Java学习笔记-7.Java IO流
    Java学习笔记-6.Java异常处理
    Java学习笔记-5.常用数据结构
    Java学习笔记-4.继承与多态
    Java学习笔记-3.类与对象
    C语言学习笔记-10.文件
    .net core 中threadpool用法
  • 原文地址:https://www.cnblogs.com/liubin0509/p/2331071.html
Copyright © 2020-2023  润新知