DSA 
DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!也就是说传输中的数据可以不再加密,接收方获得数据后,拿到公钥与签名比对数据是否有效!

通过java代码实现如下:Coder类见 java加密技术(一) 
Java代码

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.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map; /**
* DSA安全编码组件
*
*/
public abstract class DSACoder extends Coder {
/**
* 可以使用DSA方式获得签名,也可以使用RSA方式获得签名,注意成对儿出现。
*
* <code>
* public static final String KEY_ALGORITHM = "RSA";
* public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
* </code>
**/
public static final String KEY_ALGORITHM = "DSA";
public static final String SIGNATURE_ALGORITHM = "DSA"; /**
* 默认种子
*/
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(KEY_ALGORITHM); // 取私钥匙对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
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); // KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公钥匙对象
PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
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(KEY_ALGORITHM);
// 初始化随机产生器
SecureRandom secureRandom = new SecureRandom();
secureRandom.setSeed(seed.getBytes());
keygen.initialize(1024, secureRandom); KeyPair keys = keygen.genKeyPair(); PublicKey publicKey = keys.getPublic();
PrivateKey privateKey = 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());
}
} 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.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map; /**
* DSA安全编码组件
*
*/
public abstract class DSACoder extends Coder {
/**
* 可以使用DSA方式获得签名,也可以使用RSA方式获得签名,注意成对儿出现。
*
* <code>
* public static final String KEY_ALGORITHM = "RSA";
* public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
* </code>
**/
public static final String KEY_ALGORITHM = "DSA";
public static final String SIGNATURE_ALGORITHM = "DSA"; /**
* 默认种子
*/
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(KEY_ALGORITHM); // 取私钥匙对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
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); // KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公钥匙对象
PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
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(KEY_ALGORITHM);
// 初始化随机产生器
SecureRandom secureRandom = new SecureRandom();
secureRandom.setSeed(seed.getBytes());
keygen.initialize(1024, secureRandom); KeyPair keys = keygen.genKeyPair(); PublicKey publicKey = keys.getPublic();
PrivateKey privateKey = 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());
}
} 不仅可以使用DSA算法,同样也可以使用RSA算法做数字签名,但要注意成对出现:
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; 再给出一个测试类:
Java代码
import static org.junit.Assert.*; 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); } } import static org.junit.Assert.*; 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); }
}

控制台输出: 
Console代码 
公钥:   
MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp   
RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn   
xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE   
C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ   
FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo   
g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv   
5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd9   
21XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=   
  
私钥:   
MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2   
USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4   
O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC   
ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB   
gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR   
kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q   
  
签名:   
MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs=   
  
状态:   
true

公钥: 
MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp 
RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn 
xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE 
C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ 
FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo 
g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv 
5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd9 
21XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=

私钥: 
MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2 
USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4 
O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC 
ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB 
gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR 
kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q

签名: 
MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs=

状态: 
true

JAVA加密算法(DSA)的更多相关文章

  1. 基本的java加密算法MD5等等

    简单的java加密算法有: BASE64       严格地说,属于编码格式,而非加密算法 MD5             (Message Digest algorithm 5,信息摘要算法) SH ...

  2. Java加密算法 RSA

    Java加密算法 RSA 2015-06-06 08:44 511人阅读 评论(0) 收藏 举报  分类: JAVA(57)  公钥加密也称为非对称加密.速度慢.加密和解密的钥匙不相同,某一个人持有私 ...

  3. java加密算法入门(二)-对称加密详解

    1.简单介绍 什么是对称加密算法? 对称加密算法即,加密和解密使用相同密钥的算法. 优缺点: 优点:算法公开.计算量小.加密速度快.加密效率高. 缺点: (1)交易双方都使用同样钥匙,安全性得不到保证 ...

  4. java加密算法入门(三)-非对称加密详解

    1.简单介绍 这几天一直在看非对称的加密,相比之前的两篇内容,这次看了两倍多的时间还云里雾里的,所以这篇文章相对之前的两篇,概念性的东西多了些,另外是代码的每一步我都做了介绍,方便自己以后翻阅,也方便 ...

  5. MD5加盐 Java加密算法

    MD5带盐值的java加密算法   import java.security.MessageDigest; public class PasswordEncoder { private final s ...

  6. java加密算法入门(一)-算法概念及单向加密

    说起加密,我的第一印象就是电视剧各种密码本破解解密的场景,这两天在看加密相关的东西,做下笔记以便以后查看,也提供给大家个参考. 本文是java加密的第一篇,主要讲述下消息编码Base64以及简单的消息 ...

  7. Java数字签名——DSA算法

    RSA数字加密算法参考:http://www.cnblogs.com/LexMoon/p/javaRSA.html DSS: 数字签名标准 DSA: 数字签名算法 DSA仅仅包含数字签名 —————— ...

  8. Java加密算法

    密码的常用术语: 1.密码体制:由明文空间.密文空间.密钥空间.加密算法和解密算法5部分组成. 2.密码协议:也称为安全协议,是指以密码学为基础的消息交换的通信协议,目的是在网络环境中提供安全的服务. ...

  9. [转]Java加密算法

    如基本的单向加密算法: BASE64 严格地说,属于编码格式,而非加密算法 MD5(Message Digest algorithm 5,信息摘要算法) SHA(Secure Hash Algorit ...

随机推荐

  1. 洛谷P1319压缩技术 题解

    题目传送门 这道题是入门难度的题.特别水...QWQ...... #include<bits/stdc++.h> using namespace std; *],top; int main ...

  2. IOS - Safari中click点击事件无效

    做web移动端页面时,安卓端一点问题也没,发现在ios真机上点击事件无效,发现Safari下只有默认可点击的元素才click点击事件,像span div等元素是不具有点击事件的. 解决问题四种方式: ...

  3. 三年.NET即将转Java,我该何去何从

    2014年5月,大三报了某培训班5个月学习.NET 2014年12月-2015年6月,在某软件公司实习,用ASP.NET开发企业级系统 2015年7月-2017年3月,从毕业生到成为该公司的主要开发人 ...

  4. ul>li中自定义属性后取值的问题

    动态赋值的li: $.ajax({ type: "POST", url: "${base}/before/subDemand/listType", succes ...

  5. Spark 源码解析:TaskScheduler的任务提交和task最佳位置算法

    上篇文章<  Spark 源码解析 : DAGScheduler中的DAG划分与提交 >介绍了DAGScheduler的Stage划分算法. 本文继续分析Stage被封装成TaskSet, ...

  6. github 笔记(一)

    笔记预留 0. echo "# Try" >> README.md git init git add README.md git commit -m "fir ...

  7. 湖南大学ACM程序设计新生杯大赛(同步赛)H - Yuanyuan Long and His Ballons

    题目描述 Yuanyuan Long is a dragon like this picture?                                     I don’t know, ...

  8. CodeForces 805E Ice cream coloring

    直觉,构造. 画了几个样例,发现可以随便构造......先构造根节点的完全图,每个点置为不同的颜色,然后构造儿子节点的完全图...... #include <cstdio> #includ ...

  9. hihocoder 1490 Tree Restoration

    构造. 从最后一层开始往上构造.最后一层肯定都是叶子结点,距离为2的肯定是同一个父亲,确定好了父亲之后,可以确定上一层每个节点之间的距离,以及上一层每个节点到还未确定的叶子节点之间的距离. #incl ...

  10. python3 爬虫之爬取安居客二手房资讯(第一版)

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- # Author;Tsukasa import requests from bs4 import Beau ...