激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 常用數字簽名算法RSA與DSA的Java程序內實現示例

常用數字簽名算法RSA與DSA的Java程序內實現示例

2020-04-15 11:34匆忙擁擠repeat JAVA教程

這篇文章主要介紹了常用數字簽名算法RSA與DSA的Java程序內實現示例,一般來說DSA算法用于簽名的效率會比RSA要快,需要的朋友可以參考下

RSA加密算法
我們來回顧一下RSA的加密算法。我們從公鑰加密算法和簽名算法的定義出發,用比較規范的語言來描述這一算法。
RSA公鑰加密體制包含如下3個算法:KeyGen(密鑰生成算法),Encrypt(加密算法)以及Decrypt(解密算法)。
密鑰生成算法以安全常數作為輸入,輸出一個公鑰PK,和一個私鑰SK。安全常數用于確定這個加密算法的安全性有多高,一般以加密算法使用的質數p的大小有關。越大,質數p一般越大,保證體制有更高的安全性。在RSA中,密鑰生成算法如下:算法首先隨機產生兩個不同大質數p和q,計算N=pq。隨后,算法計算歐拉函數。接下來,算法隨機選擇一個小于的整數e,并計算e關于的模反元素d。最后,公鑰為PK=(N, e),私鑰為SK=(N, d)。
加密算法以公鑰PK和待加密的消息M作為輸入,輸出密文CT。在RSA中,加密算法如下:算法直接輸出密文為
解密算法以私鑰SK和密文CT作為輸入,輸出消息M。在RSA中,解密算法如下:算法直接輸出明文為。由于e和d在下互逆,因此我們有:
所以,從算法描述中我們也可以看出:公鑰用于對數據進行加密,私鑰用于對數據進行解密。當然了,這個也可以很直觀的理解:公鑰就是公開的密鑰,其公開了大家才能用它來加密數據。私鑰是私有的密鑰,誰有這個密鑰才能夠解密密文。否則大家都能看到私鑰,就都能解密,那不就亂套了。
下面就來看一下Java中的簡單實現:

?
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
package com.stone.security;
 
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Arrays;
 
import javax.crypto.Cipher;
 
/**
 * RSA算法 公鑰加密 非對稱加密
 */
public class RSA {
 public static final String KEY_ALGORITHM = "RSA";
 public static final String CIPHER_ALGORITHM_ECB1 = "RSA/ECB/PKCS1Padding";
 public static final String CIPHER_ALGORITHM_ECB2 = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding"; //不能用
 public static final String CIPHER_ALGORITHM_ECB3 = "OAEPWithSHA-256AndMGF1Padding"; //不能用
 
 static PublicKey publicKey;
 static PrivateKey privateKey;
 static Cipher cipher;
 static KeyPair keyPair;
 
 public static void main(String[] args) throws Exception {
 method1("斯柯達U*(Sfsad7f()*^%%$");
 method2("斯柯達U*(Sfsad7f()*^%%$");
 method3("斯柯達U*(Sfsad7f()*^%%$");
  
 }
 
 /**
 * 公鑰加密,私鑰解密 使用默認CIPHER_ALGORITHM_ECB1
 * @param str
 * @throws Exception
 */
 static void method1(String str) throws Exception {
 KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
 KeyPair keyPair = keyGenerator.generateKeyPair();
 publicKey = keyPair.getPublic();
 privateKey = keyPair.getPrivate();
 cipher = Cipher.getInstance(KEY_ALGORITHM);
 cipher.init(Cipher.ENCRYPT_MODE, publicKey); //公鑰加密
 byte[] encrypt = cipher.doFinal(str.getBytes());
 System.out.println("公鑰加密后1:" + Arrays.toString(encrypt));
  
 cipher.init(Cipher.DECRYPT_MODE, privateKey);//私鑰解密
 byte[] decrypt = cipher.doFinal(encrypt);
 System.out.println("私鑰解密后1:" + new String(decrypt));
 }
 
 /**
 * 私鑰加密,公鑰解密 使用默認CIPHER_ALGORITHM_ECB1
 * @param str
 * @throws Exception
 */
 static void method2(String str) throws Exception {
 KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
 KeyPair keyPair = keyGenerator.generateKeyPair();
 publicKey = keyPair.getPublic();
 privateKey = keyPair.getPrivate();
 cipher = Cipher.getInstance(KEY_ALGORITHM);
 cipher.init(Cipher.ENCRYPT_MODE, privateKey); //私鑰加密
 byte[] encrypt = cipher.doFinal(str.getBytes());
 System.out.println("私鑰加密后2:" + Arrays.toString(encrypt));
  
 cipher.init(Cipher.DECRYPT_MODE, publicKey);//公鑰解密
 byte[] decrypt = cipher.doFinal(encrypt);
 System.out.println("公鑰解密后2:" + new String(decrypt));
 }
 
 /**
 * 私鑰加密,公鑰解密 使用CIPHER_ALGORITHM_ECB1 = RSA/ECB/PKCS1Padding
 * @param str
 * @throws Exception
 */
 static void method3(String str) throws Exception {
 KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
 KeyPair keyPair = keyGenerator.generateKeyPair();
 publicKey = keyPair.getPublic();
 privateKey = keyPair.getPrivate();
 cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB1);
 cipher.init(Cipher.ENCRYPT_MODE, privateKey); //私鑰加密
 byte[] encrypt = cipher.doFinal(str.getBytes());
 System.out.println("私鑰加密后3:" + Arrays.toString(encrypt));
  
 cipher.init(Cipher.DECRYPT_MODE, publicKey);//公鑰解密
 byte[] decrypt = cipher.doFinal(encrypt);
 System.out.println("公鑰解密后3:" + new String(decrypt));
 }
}

DSA算法和數字簽名
DSA 一般用于數字簽名和認證。
DSA是Schnorr和ElGamal簽名算法的變種,被美國NIST作為DSS(DigitalSignature Standard)。
DSA是基于整數有限域離散對數難題的,其安全性與RSA相比差不多。
在DSA數字簽名和認證中,發送者使用自己的私鑰對文件或消息進行簽名,接受者收到消息后使用發送者的公鑰
來驗證簽名的真實性。DSA只是一種算法,和RSA不同之處在于它不能用作加密和解密,也不能進行密鑰交換,
只用于簽名,它比RSA要快很多.

?
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
180
181
182
183
184
185
186
package com.stone.security;
 
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.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
 
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
 
/**
 * DSA-Digital Signature Algorithm 是Schnorr和ElGamal簽名算法的變種,被美國NIST作為DSS(DigitalSignature Standard)。
 * 簡單的說,這是一種更高級的驗證方式,用作數字簽名。不單單只有公鑰、私鑰,還有數字簽名。私鑰加密生成數字簽名,公鑰驗證數據及簽名。
 * 如果數據和簽名不匹配則認為驗證失敗!即 傳輸中的數據 可以不再加密,接收方獲得數據后,拿到公鑰與簽名 驗證數據是否有效
 */
public class DSA {
 /**
 *不僅可以使用DSA算法,同樣也可以使用RSA算法做數字簽名
 */
 public static final String KEY_ALGORITHM = "RSA";
 public static final String SIGNATURE_ALGORITHM = "MD5withRSA";*/
 
 public static final String KEY_ALGORITHM = "DSA";
 public static final String SIGNATURE_ALGORITHM = "DSA";
 
 public static final String DEFAULT_SEED = "$%^*%^()(HJG8awfjas7"; //默認種子
 public static final String PUBLIC_KEY = "DSAPublicKey";
 public static final String PRIVATE_KEY = "DSAPrivateKey";
 
 public static void main(String[] args) throws Exception {
 String str = "!@#$!#^$#&ZXVDF呆軍工路愛著你*()_+";
 byte[] data = str.getBytes();
  
 Map<String, Object> keyMap = initKey();// 構建密鑰
 PublicKey publicKey = (PublicKey) keyMap.get(PUBLIC_KEY);
 PrivateKey privateKey = (PrivateKey) keyMap.get(PRIVATE_KEY);
 System.out.println("私鑰format:" + privateKey.getFormat());
 System.out.println("公鑰format:" + publicKey.getFormat());
  
  
 // 產生簽名
 String sign = sign(data, getPrivateKey(keyMap));
  
 // 驗證簽名
 boolean verify1 = verify("aaa".getBytes(), getPublicKey(keyMap), sign);
 System.err.println("經驗證 數據和簽名匹配:" + verify1);
  
 boolean verify = verify(data, getPublicKey(keyMap), sign);
 System.err.println("經驗證 數據和簽名匹配:" + verify);
 }
 
 /**
 * 生成密鑰
 *
 * @param seed 種子
 * @return 密鑰對象
 * @throws Exception
 */
 public static Map<String, Object> initKey(String seed) throws Exception {
 System.out.println("生成密鑰");
  
 KeyPairGenerator keygen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
 SecureRandom secureRandom = new SecureRandom();
 secureRandom.setSeed(seed.getBytes());
 //Modulus size must range from 512 to 1024 and be a multiple of 64
 keygen.initialize(640, secureRandom);
  
 KeyPair keys = keygen.genKeyPair();
 PrivateKey privateKey = keys.getPrivate();
 PublicKey publicKey = keys.getPublic();
  
 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()); //base64加密私鑰
 }
 
 /**
 * 取得公鑰
 *
 * @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()); //base64加密公鑰
 }
 
 /**
 * 用私鑰對信息進行數字簽名
 * @param data 加密數據
 * @param privateKey 私鑰-base64加密的
 * @return
 * @throws Exception
 */
 public static String sign(byte[] data, String privateKey) throws Exception {
 System.out.println("用私鑰對信息進行數字簽名");
  
 byte[] keyBytes = decryptBASE64(privateKey);
 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
 KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
 PrivateKey priKey = factory.generatePrivate(keySpec);//生成 私鑰
  
 //用私鑰對信息進行數字簽名
 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
 signature.initSign(priKey);
 signature.update(data);
 return encryptBASE64(signature.sign());
 }
 
 /**
 * BASE64Encoder 加密
 * @param data 要加密的數據
 * @return 加密后的字符串
 */
 private static String encryptBASE64(byte[] data) {
 BASE64Encoder encoder = new BASE64Encoder();
 String encode = encoder.encode(data);
 return encode;
 }
 
 /**
 * BASE64Decoder 解密
 * @param data 要解密的字符串
 * @return 解密后的byte[]
 * @throws Exception
 */
 private static byte[] decryptBASE64(String data) throws Exception {
 BASE64Decoder decoder = new BASE64Decoder();
 byte[] buffer = decoder.decodeBuffer(data);
 return buffer;
 }
 
 /**
 * 校驗數字簽名
 * @param data 加密數據
 * @param publicKey
 * @param sign 數字簽名
 * @return
 * @throws Exception
 */
 public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
 byte[] keyBytes = decryptBASE64(publicKey);
 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 PublicKey pubKey = keyFactory.generatePublic(keySpec);
  
 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
 signature.initVerify(pubKey);
 signature.update(data);
  
 return signature.verify(decryptBASE64(sign)); //驗證簽名
 }
 
}

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品午夜在线观看 | 国产一级毛片高清视频 | 久久久日韩精品一区二区 | 91精品国产乱码久久久久久久久 | 97中文字幕在线观看 | 久久综合福利 | 一分钟免费观看完整版电影 | 成人福利免费在线观看 | 黄网站免费观看视频 | 激情视频免费看 | 国产成年人小视频 | 主人在调教室性调教女仆游戏 | 国产美女视频一区 | 国产又粗又爽又深的免费视频 | 久久9久久 | 电影av在线 | 毛片电影在线看 | 亚洲精品欧美二区三区中文字幕 | 黄色作爱视频 | av在线更新 | 久久国产精品无码网站 | 欧洲精品视频在线观看 | 亚洲国产精久久久久久久 | 72pao成人国产永久免费视频 | 欧美一级鲁丝片免费看 | 精品在线一区二区三区 | www.国产一区.com | 中文字幕在线观看视频www | 欧美久久久一区二区三区 | 欧美aⅴ视频 | 国产精品美女一区二区 | 日本黄色免费片 | 国产精品视频成人 | 超碰99在线观看 | 成人综合一区二区 | 精国产品一区二区三区 | 全黄性性激高免费视频 | 国产精品久久久久国产精品三级 | 日韩视频一区在线 | 久久华人| 国产精品色在线网站 |