概述

信息安全基本概念:

  • DSA算法(Digital Signature Algorithm,数据签名算法)

DSA

  Digital Signature Algorithm (DSA)是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSfS(DigitalSignature Standard)。

  简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!

算法分类

算法 密钥长度 默认长度 签名长度 实现的方
SHA1withDSA 512-65536
(64的整数倍)
1024 同密钥 JDK
SHA224withDSA 同上 1024 同密钥 BC
SHA256withDSA ... 1024 同密钥 BC
SHA384withDSA ... 1024 同密钥 BC
SHA512withDSA ... 1024 同密钥 BC

签名示例

  1. import java.security.KeyFactory;
  2. import java.security.KeyPair;
  3. import java.security.KeyPairGenerator;
  4. import java.security.PrivateKey;
  5. import java.security.PublicKey;
  6. import java.security.Signature;
  7. import java.security.spec.PKCS8EncodedKeySpec;
  8. import java.security.spec.X509EncodedKeySpec;
  9.  
  10. import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
  11.  
  12. import sun.security.provider.DSAPrivateKey;
  13. import sun.security.provider.DSAPublicKey;
  14.  
  15. public class DSA {
  16. private static String src = "dsa security";
  17. public static void main(String[] args) {
  18. jdkDSA();
  19. }
  20.  
  21. public static void jdkDSA(){
  22. try {
  23. //1.初始化密钥
  24. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
  25. keyPairGenerator.initialize(512);
  26. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  27. DSAPublicKey dsaPublicKey = (DSAPublicKey)keyPair.getPublic();
  28. DSAPrivateKey dsaPrivateKey = (DSAPrivateKey)keyPair.getPrivate();
  29.  
  30. //2.执行签名
  31. PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded());
  32. KeyFactory keyFactory = KeyFactory.getInstance("DSA");
  33. PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
  34. Signature signature = Signature.getInstance("SHA1withDSA");
  35. signature.initSign(privateKey);
  36. signature.update(src.getBytes());
  37. byte[] res = signature.sign();
  38. System.out.println("签名:"+HexBin.encode(res));
  39.  
  40. //3.验证签名
  41. X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey.getEncoded());
  42. keyFactory = KeyFactory.getInstance("DSA");
  43. PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
  44. signature = Signature.getInstance("SHA1withDSA");
  45. signature.initVerify(publicKey);
  46. signature.update(src.getBytes());
  47. boolean bool = signature.verify(res);
  48. System.out.println("验证:"+bool);
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. }
  52.  
  53. }
  54. }

示例代码

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

测试代码

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

输出

  1. 公钥:
  2. MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd921XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=
  3. 私钥:
  4. MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q
  5. 签名:
  6. MCwCFGQHO9AO70cMxFTPeYqAwq7B7OFxAhRGC8A6YwFFZSfuVTAfleDof/yGug==
  7. 状态:
  8. true

参考地址:

http://snowolf.iteye.com/blog/382749

DSA算法

java-信息安全(十)-数字签名算法DSA的更多相关文章

  1. JAVA加解密 -- 数字签名算法

    数字签名 – 带有密钥的消息摘要算法 作用:验证数据完整性.认证数据来源.抗否认(OSI参考模型) 私钥签名,公钥验证 RSA 包含非对称算法和数字签名算法 实现代码: //1.初始化密钥 KeyPa ...

  2. 第十四章 数字签名算法--RSA

    注意:本节内容主要参考自 <Java加密与解密的艺术(第2版)>第9章“带密钥的消息摘要算法--数字签名算法” <大型分布式网站架构(设计与实践)>第3章“互联网安全架构” 1 ...

  3. Java数字签名算法--RSA

    签名具有的特性: 安全性 抗否认性 数字签名:带有密钥(公钥.私钥)的消息摘要算法(使用私钥进行签名,使用公钥进行验证) 数字签名算法:RSA.DSA.ECDSA 数字签名特性: 验证数据完整性 认证 ...

  4. “全栈2019”Java第十六章:下划线在数字中的意义

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. .NET Core加解密实战系列之——消息摘要与数字签名算法

    目录 简介 功能依赖 消息摘要算法 MD算法 家族发展史 应用场景 代码实现 MD5 示例代码 SHA算法 应用场景 代码实现 SHA1 SHA256 示例代码 MAC算法 HMAC算法的典型应用 H ...

  6. ECDSA数字签名算法

    一.ECDSA概述 椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟.ECDSA于1999年成为ANSI标准,并于2000年成为IEEE和NIST标准.它在 ...

  7. JAVA第十周《网络编程》学习内容总结

    JAVA第十周<网络编程>学习内容总结 学习内容总结 1.初听到网络编程四个字可能会觉得很困难,实际上网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据,把数据发送到指定的位置, ...

  8. “全栈2019”Java第十五章:Unicode与转义字符

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  9. 数字签名算法rsa

    数字签名算法消息传递模型 由消息发送方构建密钥对,这里由甲方完成. 由消息发送方公布公钥至消息接收方,这里由甲方将公钥公布给乙方. 注意如加密算法区别,这里甲方使用私钥对数据签名,数据与签名形成一则消 ...

随机推荐

  1. web前端不可错过的开发工具–Adobe Brackets

    Adobe Brackets是一个开源的基于HTML/CSS/JavaScript开发,运行在native shell上的集成开发环境.该项目由Adobe创建和维护,根据MIT许可证发布.提供Wind ...

  2. Convert a VMDK (VMWare) file to VHDX (Hyper-V)

    https://www.meziantou.net/2016/09/09/convert-a-vmdk-vmware-file-to-vhdx-hyper-v Microsoft provides a ...

  3. java计算某个坐标是否在范围内

    java电子围栏 圆.矩形.多边形算法 http://blog.csdn.net/deepak192/article/details/79402694/ java-经纬度有关的计算(半径内的经纬度范围 ...

  4. CocosCreator核心概念里的基础点

    1,锚点:是节点位置的参照点,也是自身旋转,缩放的基准点,也是子节点坐标原点.X.Y描述横纵向的锚点位置.注:锚点的取值是可以超过(0,0)~(1,1),即锚点并不在节点尺寸范围内. 2,子节点:子节 ...

  5. AFN和GCD并行同步问题

    链接: GCD 中组队列group与Afnetworking的结合使用 使用AFNetworking3.0实现接口异步并发 从并发编程到GCD浅述之一----任务.队列.线程复用.AFN3.0同步请求 ...

  6. SpringBoot在自定义类中调用service层等Spring其他层

    解决方案: 1.上代码 @Component public class ServerHandler extends IoHandlerAdapter { @Autowired protected He ...

  7. android: 碎片的demo

    现在你已经将关于碎片的重要知识点都掌握得差不多了,不过在灵活运用方面可能还有 些欠缺,因此又该进入我们本章的最佳实践环节了. 前面有提到过,碎片很多时候都是在平板开发当中使用的,主要是为了解决屏幕空间 ...

  8. android:ListView bbs Demo

    我们制 作的 message_left.9.png 可以作为收到消息的背景图,那么毫无疑问你还需要再制作一张 message_right.9.png 作为发出消息的背景图. 图片都提供好了之后就可以开 ...

  9. facebook's HipHop for PHP: Move Fast

    One of the key values at Facebook is to move fast. For the past six years, we have been able to acco ...

  10. log4j配置输出到多个日志文件

    通常我们项目里,有一些重要的日志想单独的输出到指定的文件,而不是全总输出到系统的日志文件中.那么我们log4j为我们提供了这种功能,以下我们来一步一步看是怎么做的.这里以property的配置方式写. ...