JAVA加密算法(DSA)
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)的更多相关文章
- 基本的java加密算法MD5等等
简单的java加密算法有: BASE64 严格地说,属于编码格式,而非加密算法 MD5 (Message Digest algorithm 5,信息摘要算法) SH ...
- Java加密算法 RSA
Java加密算法 RSA 2015-06-06 08:44 511人阅读 评论(0) 收藏 举报 分类: JAVA(57) 公钥加密也称为非对称加密.速度慢.加密和解密的钥匙不相同,某一个人持有私 ...
- java加密算法入门(二)-对称加密详解
1.简单介绍 什么是对称加密算法? 对称加密算法即,加密和解密使用相同密钥的算法. 优缺点: 优点:算法公开.计算量小.加密速度快.加密效率高. 缺点: (1)交易双方都使用同样钥匙,安全性得不到保证 ...
- java加密算法入门(三)-非对称加密详解
1.简单介绍 这几天一直在看非对称的加密,相比之前的两篇内容,这次看了两倍多的时间还云里雾里的,所以这篇文章相对之前的两篇,概念性的东西多了些,另外是代码的每一步我都做了介绍,方便自己以后翻阅,也方便 ...
- MD5加盐 Java加密算法
MD5带盐值的java加密算法 import java.security.MessageDigest; public class PasswordEncoder { private final s ...
- java加密算法入门(一)-算法概念及单向加密
说起加密,我的第一印象就是电视剧各种密码本破解解密的场景,这两天在看加密相关的东西,做下笔记以便以后查看,也提供给大家个参考. 本文是java加密的第一篇,主要讲述下消息编码Base64以及简单的消息 ...
- Java数字签名——DSA算法
RSA数字加密算法参考:http://www.cnblogs.com/LexMoon/p/javaRSA.html DSS: 数字签名标准 DSA: 数字签名算法 DSA仅仅包含数字签名 —————— ...
- Java加密算法
密码的常用术语: 1.密码体制:由明文空间.密文空间.密钥空间.加密算法和解密算法5部分组成. 2.密码协议:也称为安全协议,是指以密码学为基础的消息交换的通信协议,目的是在网络环境中提供安全的服务. ...
- [转]Java加密算法
如基本的单向加密算法: BASE64 严格地说,属于编码格式,而非加密算法 MD5(Message Digest algorithm 5,信息摘要算法) SHA(Secure Hash Algorit ...
随机推荐
- mac下docker中安装nodejs
一.首先下载docker并安装 https://download.docker.com/mac/stable/Docker.dmg 然后启动docker, 二.获取node最新镜像 输入来着node版 ...
- char *s 和char s[]的区别
char *s 和 char s[] 的区别小结 博客分类: C语言 c教育 . 最近的项目中有不少c的程序,在与项目新成员的交流中发现,普遍对于char *s1 和 char s2[] 认识有误区( ...
- Codeforces Round #302 (Div. 1) D - Road Improvement 树形dp
D - Road Improvemen 思路:0没有逆元!!!! 不能直接除,要求前缀积和后缀积!!! #include<bits/stdc++.h> #define LL long lo ...
- Maven下载安装步骤
Maven下载安装步骤 1.下载maven 进入Maven官网的下载页面:http://maven.apache.org/download.cgi,如下图所示: 选择当前最新版本:"apac ...
- 网站优化:引用CDN公共库
什么是CDN公共库? CDN公共库是指将常用的JS库存放在CDN节点,以方便广大开发者直接调用.与将JS库存放在服务器单机上相比,CDN公共库更加稳定.高速.一般的CDN公共库都会包含全球所有最流行的 ...
- 转: kali msfvenom生成木马
kali msfvenom生成木马 转:https://blog.csdn.net/qq_33391644/article/details/79266724 msfvenom是msfpayload,m ...
- springMVC返回modelmap跟new hashMap的区别
今天遇到了个坑. 在springboot中 平时写接口,newHashMap,@ResponseBody 返回json对象,没什么问题 @RequestMapping("url") ...
- AppDomain.CurrentDomain.BaseDirectory是什么
AppDomain.CurrentDomain.BaseDirectory 是获取基目录,它由程序集冲突解决程序用来探测程序集.由显示的路径可以看出,它代表的是程序集所在的目录,它具有读取和写入的属性 ...
- 外行人都能看懂的SpringCloud
一.前言 只有光头才能变强 认识我的朋友可能都知道我这阵子去实习啦,去的公司说是用SpringCloud(但我觉得使用的力度并不大啊~~)... 所以,这篇主要来讲讲SpringCloud的一些基础的 ...
- Linux上用Docker部署Net Core项目
前提:本地配置好Docker环境1.构建Net Core镜像 docker pull microsoft/dotnet 2.新建一个DockerFile文件并填充内容 #基于 `microsoft/d ...