博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Java小工匠聊密码学】--数字签名-DSA
阅读量:6628 次
发布时间:2019-06-25

本文共 4588 字,大约阅读时间需要 15 分钟。

1、DSA数字签名概述

1.1 DSA加密算算法

DSA(Digital Signature Algorithm)是Schnorr和ElGamal签名算法的变种,被美国NIST作为数字签名标准(DigitalSignature Standard)。

DSA(Digital Signature Algorithm,数字签名算法,用作数字签名标准的一部分),它是另一种公开密钥算法,它不能用作加密,只用作数字签名。DSA使用公开密钥,为接受者验证数据的完整性和数据发送者的身份。它也可用于由第三方去确定签名和所签数据的真实性。DSA算法的安全性基于解离散对数的困难性,这类签字标准具有较大的兼容性和适用性,成为网络安全体系的基本构件之一。

2、DSA数字签名算法分类

DSA只能与SHA-1一起使用。

3、DSA数字签名实现

3.1 JDK实现

package lzf.cipher.jdk;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;/** * @author java小工匠 */public class JdkSignatureDsaUtils {    public static final String DSA = "DSA";    public static final String MD5withDSA = "SHAwithDSA";    // 初始化密钥对    public static KeyPair initKey() {        try {            KeyPairGenerator generator = KeyPairGenerator.getInstance(DSA);            // 512 -65536 && 64 的倍数            generator.initialize(1024);            return generator.generateKeyPair();        } catch (NoSuchAlgorithmException e) {            throw new RuntimeException(e);        }    }    // 获取公钥    public static byte[] getPublicKey(KeyPair keyPair) {        byte[] bytes = keyPair.getPublic().getEncoded();        return bytes;    }    // 获取公钥    public static String getPublicKeyStr(KeyPair keyPair) {        byte[] bytes = keyPair.getPublic().getEncoded();        return encodeHex(bytes);    }    // 获取私钥    public static byte[] getPrivateKey(KeyPair keyPair) {        byte[] bytes = keyPair.getPrivate().getEncoded();        return bytes;    }    // 获取私钥    public static String getPrivateKeyStr(KeyPair keyPair) {        byte[] bytes = keyPair.getPrivate().getEncoded();        return encodeHex(bytes);    }    // 签名    public static byte[] sign(byte[] data, byte[] privateKey, String type) {        try {            // 还原使用            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);            KeyFactory keyFactory = KeyFactory.getInstance(DSA);            PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);            // 1、实例化Signature            Signature signature = Signature.getInstance(type);            // 2、初始化Signature            signature.initSign(priKey);            // 3、更新数据            signature.update(data);            // 4、签名            return signature.sign();        } catch (Exception e) {            throw new RuntimeException(e);        }    }    // 验证    public static boolean verify(byte[] data, byte[] publicKey, byte[] sign, String type) {        try {            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);            KeyFactory keyFactory = KeyFactory.getInstance(DSA);            PublicKey pubKey = keyFactory.generatePublic(keySpec);            // 1、实例化Signature            Signature signature = Signature.getInstance(type);            // 2、初始化Signature            signature.initVerify(pubKey);            // 3、更新数据            signature.update(data);            // 4、签名            return signature.verify(sign);        } catch (Exception e) {            throw new RuntimeException(e);        }    }    // 数据准16进制编码    public static String encodeHex(final byte[] data) {        return encodeHex(data, true);    }    // 数据转16进制编码    public static String encodeHex(final byte[] data, final boolean toLowerCase) {        final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };        final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };        final char[] toDigits = toLowerCase ? DIGITS_LOWER : DIGITS_UPPER;        final int l = data.length;        final char[] out = new char[l << 1];        // two characters form the hex value.        for (int i = 0, j = 0; i < l; i++) {            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];            out[j++] = toDigits[0x0F & data[i]];        }        return new String(out);    }    public static void main(String[] args) {        String str = "java小工匠";        byte[] data = str.getBytes();        // 初始化密钥度        KeyPair keyPair = initKey();        byte[] publicKey = getPublicKey(keyPair);        byte[] privateKey = getPrivateKey(keyPair);        // 签名        String type = MD5withDSA;        byte[] sign = sign(str.getBytes(), privateKey, type);        // 验证        boolean b = verify(data, publicKey, sign, type);        System.out.println("验证:" + b);    }}

转载地址:http://vmqpo.baihongyu.com/

你可能感兴趣的文章
菜品管理系统小结
查看>>
表格读取一定记录换行
查看>>
dedecms出现Error: Errno:0 SQL::错误解决方法
查看>>
Windows 2008 IIS7备份、还原站点配置 appcmd命令
查看>>
maven 项目配置
查看>>
vue项目,build后,刷新后页面挂掉cannot get
查看>>
好文要收藏,职业生涯规划
查看>>
云服务器离线安装MariaDB安装步骤和解决办法
查看>>
js手机短信按钮倒计时
查看>>
UIImage保存为JPG,PNG的方法
查看>>
权限管理
查看>>
QueryRunner 结果处理器
查看>>
Ant是什么
查看>>
Boot-col-sm布局
查看>>
Git彻底删除历史提交记录的方法
查看>>
pandas入门
查看>>
渐进增强 优雅降级
查看>>
angulajs中引用chart.js做报表,修改线条样式
查看>>
mysql之高可靠
查看>>
ubuntu中使用eclipse开发android,logcat显示问题
查看>>