介绍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 MVC+BootStrap+EF6.0实现简单的用户角色权限管理5
我们先直接拷贝下blank.html这个页面的代码,顺带先建立一个Home控制器,并添加Index视图.将代码拷贝进去. <!DOCTYPE html> <html lang=&qu ...
- 在虚拟机中安装红旗桌面7.0 Linux操作系统的详细图文教程
本文作者:souvc 本文出处:http://www.cnblogs.com/liuhongfeng/p/5343087.html 以下是详细的内容: 一.安装虚拟机. 安装虚拟机可以参考:在Wind ...
- Android资源(图片)命名规范
(转自:http://www.jb51.net/article/38796.htm) 图片命名注意: 1,不能以下划线("_")开头: 2,以数字加下划线("[0-9]_ ...
- logback配置详解3<filter>
logback 常用配置详解(三) <filter> <filter>: 过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一.返回DENY ...
- 如何正确的使用jquery-ajax
什么是ajax ajax全称Asynchronous Javascript And XML,就是异步javascript和xml ajax的作用 ajax通常用于异步加载网页内容,以及局部更新. 实际 ...
- Mysql 主从热备份
工作原理 首先锁定并备份主服务器数据库,从服务器导入备份的数据库,实现两个数据库的初态一样.然后把主服务器上执行过的sql语句都记录到二进制日志 Binarylog 中,从服务器会来读取这个log, ...
- (转)String、StringBuffer与StringBuilder之间区别
原文地址: http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺 ...
- 利用setns()将进程加入一个新的network namespace
1.首先使用docker创建一个容器,并获取该容器的network namespace monster@monster-Z:~$ docker run -itd --name test ubuntu ...
- ThreadLocal()理解
在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程程序. 当使用 ...
- SmallPtAMP: C++ AMP implementation of SmallPt / SmallPtGPU
前段时间突然对SmallPtGPU很感兴趣,于是自己也照葫芦画瓢搞了一个C++AMP的版本,整体跟SmallPtGPU基本相同,但是去掉了SmallPtGPU中显式计算直接光照的步骤,因而实现更加接近 ...

