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

Posted on

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

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

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

  1. 通过java代码实现如下:Coder类见 Java加密技术(一) Java代码 复制代码 收藏代码

  2. import java.security.Key;

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

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());

}

} 再给出一个测试类: Java代码 复制代码 收藏代码

  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 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. }

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);


}

} 控制台输出: 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. 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

公钥:

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,就验证成功! 相关链接: Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC Java加密技术(二)——对称加密DES&AES Java加密技术(三)——PBE算法 Java加密技术(四)——非对称加密算法RSA Java加密技术(五)——非对称加密算法的由来 Java加密技术(六)——数字签名算法DSA Java加密技术(七)——非对称加密算法最高ECC Java加密技术(八)——数字证书 Java加密技术(九)——初探SSL Java加密技术(十)——单向认证 Java加密技术(十一)——双向认证 Java加密技术(十二)——/.PFX(/.p12)&个人信息交换文件

希望本站内容对您有点用处,有什么疑问或建议请在后面留言评论
转载请注明作者(RobinChia)和出处 It so life ,请勿用于任何商业用途