介绍DSA数字签名,非对称加密的另一种实现
接下来我们介绍DSA数字签名,非对称加密的另一种实现。
DSA
DSA-Digital Signature Algorithm
是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature
Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!![]()
通过java代码实现如下:Coder类见 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.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;
- /**
- * DSA安全编码组件
- *
- * @author 梁栋
- * @version 1.0
- * @since 1.0
- */
- public abstract class DSACoder extends Coder {
- 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());
- }
- }
再给出一个测试类:
- import static org.junit.Assert.*;
- import java.util.Map;
- import org.junit.Test;
- /**
- *
- * @author 梁栋
- * @version 1.0
- * @since 1.0
- */
- 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/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
注意状态为true,就验证成功!![]()
介绍DSA数字签名,非对称加密的另一种实现的更多相关文章
- 【上】安全HTTPS-全面具体解释对称加密,非对称加密,数字签名,数字证书和HTTPS
一,对称加密 所谓对称加密.就是它们在编码时使用的密钥e和解码时一样d(e=d),我们就将其统称为密钥k. 对称加解密的步骤例如以下: 发送端和接收端首先要共享同样的密钥k(即通信前两方都须要知道相应 ...
- https处理的一个过程,对称加密和非对称加密
一,对称加密 所谓对称加密,就是它们在编码时使用的密钥e和解码时一样d(e=d),我们就将其统称为密钥k. 对称加解密的过程如下: 发送端和接收端首先要共享相同的密钥k(即通信前双方都需要知道对应的密 ...
- [svc]对称加密/非对称加密细枝末节-如何做到数据传输的authentication/data integrity/confidentiality(私密)
对称/非对称/混合加密的冷知识 数据在互联网上传输,要考虑安全性. 讲到安全,要从三方面考虑: 1.authentication 每一个IP包的认证,确保合法源的数据 2.data integrity ...
- openssl 非对称加密DSA,RSA区别与使用介绍(转)
openssl 非对称加密DSA,RSA区别与使用介绍(转) 博客分类: OS.Linux Security 在日常系统管理工作中,需要作一些加解密的工作,通过openssl工具包就能完成我们很多 ...
- openssl 非对称加密DSA,RSA区别与使用介绍
在日常系统管理工作中,需要作一些加解密的工作,通过openssl工具包就能完成我们很多需求! 1. openssl RSA 加解密 RSA是基于数论中大素数的乘积难分解理论上的非对称加密法,使用公私钥 ...
- 和安全有关的那些事(非对称加密、数字摘要、数字签名、数字证书、SSL、HTTPS及其他)
转自http://blog.csdn.net/bluishglc/article/details/7585965 对于一般的开发人员来说,很少需要对安全领域内的基础技术进行深入的研究,但是鉴于日常系统 ...
- 浅谈IM软件业务知识——非对称加密,RSA算法,数字签名,公钥,私钥
概述 首先了解一下相关概念:RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的.RSA就是取自他们三个人的名字. 算法基于一个数论:将两个大素数相乘很ea ...
- https原理及其中所包含的对称加密、非对称加密、数字证书、数字签名
声明:本文章已授权公众号Hollis转载,如需转载请标明转载自https://www.cnblogs.com/wutianqi/p/10654245.html(安静的boy) 一.为什么要使用http ...
- 对称加密、非对称加密、数字签名、数字证书、SSL是什么
非对称密钥加解密 对于一份数据,通过一种算法,基于传入的密钥(一串由数字或字符组成的字符串,也称key),将明文数据转换成了不可阅读的密文,这就是“加密”,同样的,密文到达目的地后,需要再以相应的算法 ...
随机推荐
- asp.net signalR 专题—— 第三篇 如何从外部线程访问 PersistentConnection
在前面的两篇文章中,我们讲到的都是如何将消息从server推向client,又或者是client再推向server,貌似这样的逻辑没什么异常,但是放在真实 的环境中,你会很快发现有一个新需求,如何根据 ...
- Spark存储管理(读书笔记)
Spark存储管理(读书笔记) 转载请注明出处:http://www.cnblogs.com/BYRans/ Spark的存储管理 RDD的存放和管理都是由Spark的存储管理模块实现和管理的.本文从 ...
- LLVM 笔记(五)—— LLVM IR
ilocker:关注 Android 安全(新手) QQ: 2597294287 LLVM 的 IR (Intermediate Representation) 是其设计中的最重要的部分.优化器在进行 ...
- 抓鼠标的猫(Win32实现,Codeblocks+GCC编译)
程序效果: 猫的眼睛一直跟着鼠标移动: 鼠标经过猫的右脚附近时,猫会抓住鼠标.(未使用Hook) 代码: //main.cpp 1 #include <windows.h> #includ ...
- [No00006B]方便的网络下载工具wget 可下载网站目录下的所有文件(可下载整个网站)
wget是linux下命令行的下载工具,功能很强大,它能完成某些下载软件所不能做的,比如如果你想下载一个网页目录下的所有文件,如何做呢?网络用户有时候会遇到需要下载一批文件的情况,有时甚至需要把整个网 ...
- Linux 进程间通讯详解二
消息队列 --消息队列提供了本机上从一个进程向另外一个进程发送一块数据的方法 --每个数据块都被认为有一个类型,接收者进程接收的数据块可以有不同的类型值 --消息队列也有管道一样的不足,就是每个消息的 ...
- ASP.NET Boilerplate
I want it to be a start point for all we .NET developers, so, it will be good to develop it together ...
- 解决Scala Play框架在Git Bash运行的异常:Could not find configuration file ../framework/sbt/sbt.boot.properties
Git Bash+ConEmu可以模拟Linux强大的命令行.不过在结合Scala和Play时,需要注意如下事项: 1. Scala的安装在64位操作系统下,默认会放在“C:\Program File ...
- document.forms用法
1.FF中不能接受document.forms("formname")的使用,ie中可以 最好改成document.forms["formname"]的下标用法 ...
- 【三石jQuery视频教程】02.创建 FontAwesome 复选框和单选框
视频地址:http://v.qq.com/page/m/8/c/m0150izlt8c.html 大家好,欢迎来到[三石jQuery视频教程],我是您的老朋友 - 三生石上. 今天,我们要通过基本的H ...

