概述

信息安全基本概念:

  • DSA算法(Digital Signature Algorithm,数据签名算法)

DSA

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

  简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!

算法分类

算法 密钥长度 默认长度 签名长度 实现的方
SHA1withDSA 512-65536
(64的整数倍)
1024 同密钥 JDK
SHA224withDSA 同上 1024 同密钥 BC
SHA256withDSA ... 1024 同密钥 BC
SHA384withDSA ... 1024 同密钥 BC
SHA512withDSA ... 1024 同密钥 BC

签名示例

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; import sun.security.provider.DSAPrivateKey;
import sun.security.provider.DSAPublicKey; public class DSA {
private static String src = "dsa security";
public static void main(String[] args) {
jdkDSA();
} public static void jdkDSA(){
try {
//1.初始化密钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
DSAPublicKey dsaPublicKey = (DSAPublicKey)keyPair.getPublic();
DSAPrivateKey dsaPrivateKey = (DSAPrivateKey)keyPair.getPrivate(); //2.执行签名
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signature signature = Signature.getInstance("SHA1withDSA");
signature.initSign(privateKey);
signature.update(src.getBytes());
byte[] res = signature.sign();
System.out.println("签名:"+HexBin.encode(res)); //3.验证签名
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("DSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
signature = Signature.getInstance("SHA1withDSA");
signature.initVerify(publicKey);
signature.update(src.getBytes());
boolean bool = signature.verify(res);
System.out.println("验证:"+bool);
} catch (Exception e) {
e.printStackTrace();
} }
}

示例代码

package com.jd.order.util.encryption;

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; import org.apache.commons.codec.binary.Base64; /**
* DSA数字签名组件
*
* @author 木子旭
* @since 2017年3月17日上午10:37:30
* @version %I%,%G%
*/
public class DSACoder {
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 = 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 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 = 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(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 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 encryptBASE64(key.getEncoded());
} public static byte[] decryptBASE64(String data) {
return Base64.decodeBase64(data);
} public static String encryptBASE64(byte[] data) {
return new String(Base64.encodeBase64(data));
}
}

测试代码

package com.jd.order.util.encryption;

import static org.junit.Assert.assertTrue;

import java.util.Map;

import org.junit.Test;

public class DSACoderTest {

    @Test
public void test() throws Exception {
String inputStr = "abc";
byte[] data = inputStr.getBytes(); // 构建密钥
Map<String, Object> keyMap = DSACoder.initKey(); // 获得密钥
String publicKey = DSACoder.getPublicKey(keyMap);
String privateKey = DSACoder.getPrivateKey(keyMap); System.err.println("公钥:\r" + publicKey);
System.err.println("私钥:\r" + privateKey); // 产生签名
String sign = DSACoder.sign(data, privateKey);
System.err.println("签名:\r" + sign); // 验证签名
boolean status = DSACoder.verify(data, publicKey, sign);
System.err.println("状态:\r" + status);
assertTrue(status); }
}

输出

公钥:
MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd921XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=
私钥:
MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q
签名:
MCwCFGQHO9AO70cMxFTPeYqAwq7B7OFxAhRGC8A6YwFFZSfuVTAfleDof/yGug==
状态:
true

参考地址:

http://snowolf.iteye.com/blog/382749

DSA算法

java-信息安全(十)-数字签名算法DSA的更多相关文章

  1. JAVA加解密 -- 数字签名算法

    数字签名 – 带有密钥的消息摘要算法 作用:验证数据完整性.认证数据来源.抗否认(OSI参考模型) 私钥签名,公钥验证 RSA 包含非对称算法和数字签名算法 实现代码: //1.初始化密钥 KeyPa ...

  2. 第十四章 数字签名算法--RSA

    注意:本节内容主要参考自 <Java加密与解密的艺术(第2版)>第9章“带密钥的消息摘要算法--数字签名算法” <大型分布式网站架构(设计与实践)>第3章“互联网安全架构” 1 ...

  3. Java数字签名算法--RSA

    签名具有的特性: 安全性 抗否认性 数字签名:带有密钥(公钥.私钥)的消息摘要算法(使用私钥进行签名,使用公钥进行验证) 数字签名算法:RSA.DSA.ECDSA 数字签名特性: 验证数据完整性 认证 ...

  4. “全栈2019”Java第十六章:下划线在数字中的意义

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. .NET Core加解密实战系列之——消息摘要与数字签名算法

    目录 简介 功能依赖 消息摘要算法 MD算法 家族发展史 应用场景 代码实现 MD5 示例代码 SHA算法 应用场景 代码实现 SHA1 SHA256 示例代码 MAC算法 HMAC算法的典型应用 H ...

  6. ECDSA数字签名算法

    一.ECDSA概述 椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟.ECDSA于1999年成为ANSI标准,并于2000年成为IEEE和NIST标准.它在 ...

  7. JAVA第十周《网络编程》学习内容总结

    JAVA第十周<网络编程>学习内容总结 学习内容总结 1.初听到网络编程四个字可能会觉得很困难,实际上网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据,把数据发送到指定的位置, ...

  8. “全栈2019”Java第十五章:Unicode与转义字符

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  9. 数字签名算法rsa

    数字签名算法消息传递模型 由消息发送方构建密钥对,这里由甲方完成. 由消息发送方公布公钥至消息接收方,这里由甲方将公钥公布给乙方. 注意如加密算法区别,这里甲方使用私钥对数据签名,数据与签名形成一则消 ...

随机推荐

  1. php创建udp Server

    <?php//服务器信息$server = 'udp://127.0.0.1:7002';//----UDP Server$msgEof = "\n";$socket = s ...

  2. 潭州课堂25班:Ph201805201 并发(协程) 第十五课 (课堂笔记)

    #斐波那契 def fid(n): res = [] indx = 0 a = 0 b = 1 while indx < n : res.append(b) a,b = b,a+b indx + ...

  3. [模板][P3690]Link Cut Tree

    Description: 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和 ...

  4. Github如何回退/回滚到某个版本

    当然你可以直接在命令行使用 git reset --hard <commit ID号> 或者 git reset --hard HEAD^来进行回退

  5. XMPP接受发送消息

    在现阶段的通信服务中,各种标准都有,因此会出现无法实现相互连通,而XMPP(Extensible Message and presence Protocol)协议的出现,实现了整个及时通信服务协议的互 ...

  6. 【FFmpeg】ffplay播放rtsp视频流花屏问题 (转)

    问题描述:ffplay播放rtsp视频流时,播放过程中随机出现花屏现象. 基本流程学习:阅读ffplay源码,熟悉其播放rtsp视频流的基本流程. 在ffplay源码阅读和分析的基础上,画出了其播放r ...

  7. receiving error: 'Error: SSL Error: SELF_SIGNED_CERT_IN_CHAIN' while using npm

    From:https://stackoverflow.com/questions/9626990/receiving-error-error-ssl-error-self-signed-cert-in ...

  8. hive 字段名称显示

    首先查看一个sql 1.首先存在一个数据表tmp CREATE TABLE tmp( platform string, channel string, chan_value string, uid s ...

  9. SQL与MySQL基本

    一:概念辨析 数据库(database):是一种保存有组织的数据的容器. 数据库软件(DBMS):使用DBMS操作数据库.访问数据库. SQL:结构化查询语言,专门用来与数据库通信的语言.几乎所有DB ...

  10. 使用 LaTeX 画图系列

    可以使用TikZ,用TikZ绘制出来的图形效果非常好,原生支持所有LaTeX语法. 使用 LaTeX 画柱状图/条形图参考:Guide to draw charts (basic, pie, bar) ...