java 非对称加密 DSA

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

  1. 各种Java加密算法

  2. 各种Java加密算法


通过java代码实现如下:Coder类见

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
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());
     }
}



再给出一个测试类:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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);
 
     }
 
}


控制台输出:

公钥:
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,就验证成功!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值