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

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

    博客分类:
  •  

  • Java/Security

JavaSecurity算法Blogjunit

    接下来我们介绍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  


你可能感兴趣的:(Java加密技术(六)——数字签名算法DSA)