接下来我们介绍DSA数字签名,非对称加密的另一种实现。
DSA

DSA-Digital Signature Algorithm
是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature
Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!

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

  1. import java.security.Key;
  2. import java.security.KeyFactory;
  3. import java.security.KeyPair;
  4. import java.security.KeyPairGenerator;
  5. import java.security.PrivateKey;
  6. import java.security.PublicKey;
  7. import java.security.SecureRandom;
  8. import java.security.Signature;
  9. import java.security.interfaces.DSAPrivateKey;
  10. import java.security.interfaces.DSAPublicKey;
  11. import java.security.spec.PKCS8EncodedKeySpec;
  12. import java.security.spec.X509EncodedKeySpec;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. /**
  16. * DSA安全编码组件
  17. *
  18. * @author 梁栋
  19. * @version 1.0
  20. * @since 1.0
  21. */
  22. public abstract class DSACoder extends Coder {
  23. public static final String ALGORITHM = "DSA";
  24. /**
  25. * 默认密钥字节数
  26. *
  27. * <pre>
  28. * DSA
  29. * Default Keysize 1024
  30. * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive).
  31. * </pre>
  32. */
  33. private static final int KEY_SIZE = 1024;
  34. /**
  35. * 默认种子
  36. */
  37. private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3";
  38. private static final String PUBLIC_KEY = "DSAPublicKey";
  39. private static final String PRIVATE_KEY = "DSAPrivateKey";
  40. /**
  41. * 用私钥对信息生成数字签名
  42. *
  43. * @param data
  44. *            加密数据
  45. * @param privateKey
  46. *            私钥
  47. *
  48. * @return
  49. * @throws Exception
  50. */
  51. public static String sign(byte[] data, String privateKey) throws Exception {
  52. // 解密由base64编码的私钥
  53. byte[] keyBytes = decryptBASE64(privateKey);
  54. // 构造PKCS8EncodedKeySpec对象
  55. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  56. // KEY_ALGORITHM 指定的加密算法
  57. KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
  58. // 取私钥匙对象
  59. PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
  60. // 用私钥对信息生成数字签名
  61. Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
  62. signature.initSign(priKey);
  63. signature.update(data);
  64. return encryptBASE64(signature.sign());
  65. }
  66. /**
  67. * 校验数字签名
  68. *
  69. * @param data
  70. *            加密数据
  71. * @param publicKey
  72. *            公钥
  73. * @param sign
  74. *            数字签名
  75. *
  76. * @return 校验成功返回true 失败返回false
  77. * @throws Exception
  78. *
  79. */
  80. public static boolean verify(byte[] data, String publicKey, String sign)
  81. throws Exception {
  82. // 解密由base64编码的公钥
  83. byte[] keyBytes = decryptBASE64(publicKey);
  84. // 构造X509EncodedKeySpec对象
  85. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  86. // ALGORITHM 指定的加密算法
  87. KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
  88. // 取公钥匙对象
  89. PublicKey pubKey = keyFactory.generatePublic(keySpec);
  90. Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
  91. signature.initVerify(pubKey);
  92. signature.update(data);
  93. // 验证签名是否正常
  94. return signature.verify(decryptBASE64(sign));
  95. }
  96. /**
  97. * 生成密钥
  98. *
  99. * @param seed
  100. *            种子
  101. * @return 密钥对象
  102. * @throws Exception
  103. */
  104. public static Map<String, Object> initKey(String seed) throws Exception {
  105. KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM);
  106. // 初始化随机产生器
  107. SecureRandom secureRandom = new SecureRandom();
  108. secureRandom.setSeed(seed.getBytes());
  109. keygen.initialize(KEY_SIZE, secureRandom);
  110. KeyPair keys = keygen.genKeyPair();
  111. DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic();
  112. DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate();
  113. Map<String, Object> map = new HashMap<String, Object>(2);
  114. map.put(PUBLIC_KEY, publicKey);
  115. map.put(PRIVATE_KEY, privateKey);
  116. return map;
  117. }
  118. /**
  119. * 默认生成密钥
  120. *
  121. * @return 密钥对象
  122. * @throws Exception
  123. */
  124. public static Map<String, Object> initKey() throws Exception {
  125. return initKey(DEFAULT_SEED);
  126. }
  127. /**
  128. * 取得私钥
  129. *
  130. * @param keyMap
  131. * @return
  132. * @throws Exception
  133. */
  134. public static String getPrivateKey(Map<String, Object> keyMap)
  135. throws Exception {
  136. Key key = (Key) keyMap.get(PRIVATE_KEY);
  137. return encryptBASE64(key.getEncoded());
  138. }
  139. /**
  140. * 取得公钥
  141. *
  142. * @param keyMap
  143. * @return
  144. * @throws Exception
  145. */
  146. public static String getPublicKey(Map<String, Object> keyMap)
  147. throws Exception {
  148. Key key = (Key) keyMap.get(PUBLIC_KEY);
  149. return encryptBASE64(key.getEncoded());
  150. }
  151. }

再给出一个测试类:

  1. import static org.junit.Assert.*;
  2. import java.util.Map;
  3. import org.junit.Test;
  4. /**
  5. *
  6. * @author 梁栋
  7. * @version 1.0
  8. * @since 1.0
  9. */
  10. public class DSACoderTest {
  11. @Test
  12. public void test() throws Exception {
  13. String inputStr = "abc";
  14. byte[] data = inputStr.getBytes();
  15. // 构建密钥
  16. Map<String, Object> keyMap = DSACoder.initKey();
  17. // 获得密钥
  18. String publicKey = DSACoder.getPublicKey(keyMap);
  19. String privateKey = DSACoder.getPrivateKey(keyMap);
  20. System.err.println("公钥:\r" + publicKey);
  21. System.err.println("私钥:\r" + privateKey);
  22. // 产生签名
  23. String sign = DSACoder.sign(data, privateKey);
  24. System.err.println("签名:\r" + sign);
  25. // 验证签名
  26. boolean status = DSACoder.verify(data, publicKey, sign);
  27. System.err.println("状态:\r" + status);
  28. assertTrue(status);
  29. }
  30. }

控制台输出:

  1. 公钥:
  2. MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp
  3. RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn
  4. xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE
  5. C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ
  6. FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo
  7. g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv
  8. 5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd9
  9. 21XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=
  10. 私钥:
  11. MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2
  12. USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4
  13. O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC
  14. ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB
  15. gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR
  16. kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q
  17. 签名:
  18. MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs=
  19. 状态:
  20. true

注意状态为true,就验证成功!

介绍DSA数字签名,非对称加密的另一种实现的更多相关文章

  1. 【上】安全HTTPS-全面具体解释对称加密,非对称加密,数字签名,数字证书和HTTPS

    一,对称加密 所谓对称加密.就是它们在编码时使用的密钥e和解码时一样d(e=d),我们就将其统称为密钥k. 对称加解密的步骤例如以下: 发送端和接收端首先要共享同样的密钥k(即通信前两方都须要知道相应 ...

  2. https处理的一个过程,对称加密和非对称加密

    一,对称加密 所谓对称加密,就是它们在编码时使用的密钥e和解码时一样d(e=d),我们就将其统称为密钥k. 对称加解密的过程如下: 发送端和接收端首先要共享相同的密钥k(即通信前双方都需要知道对应的密 ...

  3. [svc]对称加密/非对称加密细枝末节-如何做到数据传输的authentication/data integrity/confidentiality(私密)

    对称/非对称/混合加密的冷知识 数据在互联网上传输,要考虑安全性. 讲到安全,要从三方面考虑: 1.authentication 每一个IP包的认证,确保合法源的数据 2.data integrity ...

  4. openssl 非对称加密DSA,RSA区别与使用介绍(转)

    openssl 非对称加密DSA,RSA区别与使用介绍(转) 博客分类: OS.Linux Security   在日常系统管理工作中,需要作一些加解密的工作,通过openssl工具包就能完成我们很多 ...

  5. openssl 非对称加密DSA,RSA区别与使用介绍

    在日常系统管理工作中,需要作一些加解密的工作,通过openssl工具包就能完成我们很多需求! 1. openssl RSA 加解密 RSA是基于数论中大素数的乘积难分解理论上的非对称加密法,使用公私钥 ...

  6. 和安全有关的那些事(非对称加密、数字摘要、数字签名、数字证书、SSL、HTTPS及其他)

    转自http://blog.csdn.net/bluishglc/article/details/7585965 对于一般的开发人员来说,很少需要对安全领域内的基础技术进行深入的研究,但是鉴于日常系统 ...

  7. 浅谈IM软件业务知识——非对称加密,RSA算法,数字签名,公钥,私钥

    概述 首先了解一下相关概念:RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的.RSA就是取自他们三个人的名字. 算法基于一个数论:将两个大素数相乘很ea ...

  8. https原理及其中所包含的对称加密、非对称加密、数字证书、数字签名

    声明:本文章已授权公众号Hollis转载,如需转载请标明转载自https://www.cnblogs.com/wutianqi/p/10654245.html(安静的boy) 一.为什么要使用http ...

  9. 对称加密、非对称加密、数字签名、数字证书、SSL是什么

    非对称密钥加解密 对于一份数据,通过一种算法,基于传入的密钥(一串由数字或字符组成的字符串,也称key),将明文数据转换成了不可阅读的密文,这就是“加密”,同样的,密文到达目的地后,需要再以相应的算法 ...

随机推荐

  1. .NET应用架构设计—面向查询服务的参数化查询设计(分解业务点,单独配置各自的数据查询契约)

    阅读目录: 1.背景介绍 2.对业务功能点进行逻辑划分(如:A.B.C分别三个业务点) 2.1.配置映射关系,对业务点配置查询契约(构造VS插件方便生成查询契约) 2.2.将配置好的映射策略文件放在调 ...

  2. Fedora 23安装配置mysql数据库,修改初始密码及登陆

    下载MySQL5.7.9 yum仓库 wget http://dev.mysql.com/get/mysql57-community-release-fc23-7-noarch.rpm rpm -iv ...

  3. SQL闲杂知识点汇总【2015年12月】

    2015.12.14 知识点1:DEFAULT VALUES实现插入行 --临时创建临时表 CREATE TABLE [dbo].[tblTmp] ( iTmpID ,) NOT NULL PRIMA ...

  4. js中取得当前加载的js的src地址

    在很多js框架中看到过,如果要动态加载框架内部的其他js,加载的时候加载的地址经常是一个相对的地址,只能是这样了哦,因为框架根本不知道用此框架的用户,将框架js文件放的具体目录,所以框架中一般会采用如 ...

  5. scala Basic 第三课

    yield 在学习c#的时候学习过这个关键字,和这时的语义是一致的. 当你生成一个新的迭代器,而并不是想立刻使用,而是在其他地方使用的时候,可以延迟生成这个集合, 这时候yield关键字可以帮你完成这 ...

  6. java设计模式之中介者模式

    中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...

  7. Eclipse调试常用技巧

    1. 条件断点 断点大家都比较熟悉,在Eclipse Java 编辑区的行头双击就会得到一个断点,代码会运行到此处时停止. 条件断点,顾名思义就是一个有一定条件的断点,只有满足了用户设置的条件,代码才 ...

  8. NOIP2013pj车站分级[拓扑排序]

    题目描述 一条单向的铁路线上,依次有编号为 1, 2, …, n 的 n 个火车站.每个火车站都有一个级 别,最低为 1 级.现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车 次停靠了 ...

  9. jenkins, ant, pmd持续集成

    http://pmd.sourceforge.net/pmd-5.0.3/ant-task.html 在jenkins , ant , pmd进行集成的时候,build.xml模板如下,在网上找了一些 ...

  10. php配置参数.md

    php 5.5 配置文件 php.ini Options user_ini.filename string 设定了 PHP 会在每个目录下搜寻的文件名:如果设定为空字符串则 PHP 不会搜寻.默认值是 ...