`

Java加密技术(六)——数字签名算法DSA

    博客分类:
  • java
阅读更多

 

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


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


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

控制台输出: 
Console代码  收藏代码
  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. 私钥:  
  12. MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2  
  13. USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4  
  14. O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC  
  15. ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB  
  16. gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR  
  17. kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q  
  18.   
  19. 签名:  
  20. MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs=  
  21.   
  22. 状态:  
  23. true  


注意状态为true,就验证成功! 
分享到:
评论

相关推荐

    Java密码学(5)——数字签名算法

    总结来说,Java中的数字签名算法是通过非对称加密和散列函数相结合的方式,提供了数据完整性和发送者身份验证的能力。`CoderUtil.java`可能是一个辅助工具,用于简化数字签名的生成和验证过程。了解并熟练掌握数字...

    网络安全技术应用——数字签名技术在Java中的实现.pdf

    其核心是采用加密技术的加、解密算法体制来实现对信息的数字签名。数字签名技术的应用范围非常广泛,在保障电子数据交换的安全性上是一个突破性的进展。 在数字签名技术中,发送者使用秘密密钥对报文进行加密,将...

    非对称加密算法 数字签名算法

    同时,文件中的`非对称加密算法 数字签名算法——RSA - 信息安全 - ITeye知识库频道_files`可能包含更多示例代码和详细解释,有助于进一步学习和实践。 总之,非对称加密算法和数字签名是保障网络通信安全的重要...

    java各种加密算法

    DSA(Digital Signature Algorithm)是一种基于离散对数问题的数字签名算法,主要用于创建数字签名而非加密数据。在Java中,可以使用`java.security.KeyPairGenerator`类生成DSA密钥对,并通过`java.security....

    pdf.rar_java数字水印_pdf_pdf签名_数字签名_签名

    它通过使用公钥加密技术,将签名者的私钥与文档的哈希值结合,形成一个数字签名。用户可以使用PDF阅读器检查签名,确保文档自签名后未被修改。签名还可以包含证书信息,提供签发者身份的可信度。在Java中,可以使用...

    基于java的数字签名、数字证书生成源码.zip

    这个过程包括选择合适的算法(如RSA或DSA),对原始数据进行哈希运算,然后使用私钥对哈希结果进行加密,生成的就是数字签名。 数字证书则是一种包含公钥和相关身份信息的电子文档,通常由可信的第三方机构——证书...

    JAVA的加密算法及应用

    ### JAVA的加密算法及应用 #### 一、引言 随着信息技术的快速发展,信息安全成为了企业和个人关注的重点。...随着技术的发展,新的加密技术和算法也将不断涌现,未来的信息安全领域将会更加丰富多彩。

    基于Java的实例源码-数字签名、数字证书生成源码.zip

    在Java中,`java.security`包提供了实现数字签名的相关类,如`Signature`,它支持各种算法,如RSA、DSA等。 数字证书则是一种包含公钥和相关身份信息的电子文档,通常由可信的第三方机构——证书颁发机构(CA)签署...

    Java经典算法--加密算法

    ### Java经典算法——加密算法详解 #### 一、概述 在现代信息技术中,加密技术扮演着至关重要的角色,尤其是在保障数据安全与隐私方面。本文将详细介绍几种常用的加密算法及其在Java中的实现方式。 #### 二、对称...

    Java 数字签名、数字证书生成源码

    数字签名是一种用于验证电子信息完整性的方法,它结合了非对称加密技术。在Java中,我们可以使用`java.security`包中的类来实现这一功能。例如,`Signature`类提供了数字签名的生成和验证接口。生成数字签名通常包括...

    Java加密解密方法大全

    - DSA(Digital Signature Algorithm):专门用于数字签名的标准算法。 ##### 3.3 单向加密算法 单向加密算法(也称为哈希函数)主要用于验证数据的完整性和一致性。一旦数据被哈希处理,就无法从哈希值反推出...

    JAVA上加密算法的实现用例

    数字签名是利用公钥加密原理来确认信息来源和保障信息未被篡改的技术。发送方使用私钥对信息的摘要进行加密,形成数字签名。接收方则使用发送方的公钥验证签名,确保信息的完整性和发送方的身份。这一过程中,HASH...

    基于Java的实例源码-加密库 BeeCrypt.zip

    2. **非对称加密**:如RSA、DSA(数字签名算法)或ECC(椭圆曲线加密),使用一对公钥和私钥,公钥用于加密,私钥用于解密,增强了安全性。 3. **哈希函数**:如MD5、SHA-1或SHA-256,用于生成数据的固定长度摘要,...

    java加密代码

    ### Java加密技术概览 在Java中实现加密通常涉及到对称加密、非对对称加密(公钥/私钥加密)以及散列函数等多种方式。这些加密方法被广泛应用于保护数据安全、确保通信隐私等领域。 #### 1. 对称加密 对称加密是...

    java源代码Java课程设计Java

    在本Java课程设计中,我们将深入探讨Java编程语言的核心特性,包括线程管理和加密技术,同时结合实际项目经验,提供一份详细的实验报告和课程设计。这些主题是Java开发者必备的知识,无论是在学术研究还是在软件开发...

    非对称加密传输文件相关技术理论浅析

    在非对称加密中,常见的算法有RSA、ECC(椭圆曲线加密)和DSA(数字签名算法)。RSA是最早被广泛应用的非对称加密算法,它的安全性基于大整数因子分解的难度;ECC则以其更高的安全性与效率成为一种现代选择,尽管...

    非对称加密的案例

    在Java中,非对称加密的实现主要包括RSA、DSA和ECC等算法。RSA是最常见的一种,它基于数论上的大数因子分解难题。Java的`java.security`包提供了实现这些算法的接口和类,如`KeyPairGenerator`用于生成密钥对,`...

Global site tag (gtag.js) - Google Analytics