前后端java+vue 实现rsa 加解密与摘要签名算法

vue

1、后端生成密钥对,公钥分享给前端,前端获取到服务器给的公钥。

2、前端用服务器端给的公钥 及算法:RSA/CBC/PKCS1Padding 加密"xhy 我爱你 中国 依芸Yiyun !!!" 生成加密数据。

3、前端然后生成自己的密钥对,用自己的私钥及算法SHA1withRSA生成摘要签名。

4、前端把加密数据、自己的公钥与签名一并发给后端。

5、后端收到加密数据、签名数据、前端的公钥,先用前端公钥、签名数据、算法SHA1withRSA 验签,验签通过后再用后端的私钥、算法:RSA/CBC/PKCS7Padding 解密数据。

RSA 加密、解密、签名、验签、摘要,前后端java+vue联调测试通过

直接上代码

// 注意:加密密文与签名都是唯一的,不会变化。
// 注意:vue 端密钥都要带pem格式。java 不要带pem格式
// 注意:vue端及java端函数参数、返回值要求是什么类型及何进制。搞明白哪里用base64,哪里2进制,哪里16进制。
// 重点还是要了解点原理,比如sha1withrsa,先经过sha1算法,知道aaa,哈希后的密文16进制是:7e240de74fb1ed08fa08d38063f6a6a91462a815,对比自己的程序有没有算错。
// 利用一些在线测试工具帮忙验证自己的程序过程。http://www.metools.info/code/c82.html ; 同时知道如何查引入的类库各api的官网,了解如何使用各函数。
// 不然遇到莫名奇妙的错误无从解决。报错的地方不一定是程序实际错误的地方。了解查错的方式有:打庄、debug.

服务器端java:

工具类,rsa加解密,RsaUtil.java

  1 package com.ruoyi.common.utils.enDeCrypt;

2

3 import com.ruoyi.common.core.text.Convert;

4 import com.ruoyi.common.exception.UtilException;

5

6 import java.io.ByteArrayOutputStream;

7 import java.io.UnsupportedEncodingException;

8 import java.security.*;

9 import java.util.Base64;

10 import javax.crypto.Cipher;

11 import java.security.interfaces.RSAPrivateKey;

12 import java.security.interfaces.RSAPublicKey;

13 import java.security.spec.PKCS8EncodedKeySpec;

14 import java.security.spec.X509EncodedKeySpec;

15 import java.util.HashMap;

16 import java.util.Map;

17

18 import static io.netty.util.CharsetUtil.UTF_8;

19

20

21 /** 加密和解密花费时间长、速度慢,故使用RSA只能加密少量数据,大量的数据加密还要靠对称密码算法。

22 * 第一种用法是公钥加密、私钥解密——用于加密;第二种是私钥签名、公钥验签——用于签名

23 * @author EvianZou

24 */

25 public class RsaUtil {

26

27 /**

28 * 密钥长度与原文长度对应,越长速度越慢

29 * 1024bit 密钥 能加密明文最大的长度是 1024/8 -11 = 117 byte

30 * 2048bit 密钥 能加密明文最大的长度是 2048/8 -11 = 245 byte

31 */

32 private final static int KEY_SIZE = 1024;

33 /*

34 * RSA算法 RSA-1024位 RSA2-2048位

35 */

36 private final static String ALGORITHM = "RSA";

37 //java默认"RSA"="RSA/ECB/PKCS1Padding"

38 private final static String PADDING_MODE = "RSA";

39

40 /*

41 * 签名算法

42 * RSA: 常用 SHA1WithRSA,有 MD2withRSA、MD5withRSA、SHA1withRSA;

43 * RSA2: 常用:SHA256WithRSA,有 SHA224withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA 、RIPEMD128withRSA、RIPEMD160withRSA;

44 */

45 public static final String SIGN_ALGORITHM = "SHA1withRSA";

46

47 /*

48 * 字符编码

49 */

50 private final static String ENCODING = "UTF-8";

51

52 /*

53 * RSA最大加密明文大小

54 * RSA:117

55 * RSA2:245

56 */

57 private static final int MAX_ENCRYPT_BLOCK = 117;

58

59 /*

60 * RSA最大解密密文大小

61 * RSA:128

62 * RSA2:256

63 */

64 private static final int MAX_DECRYPT_BLOCK = 128;

65

66 public Map<String, String> getKeyMap() {

67 return keyMap;

68 }

69

70 public void setKeyMap(Map<String, String> keyMap) {

71 this.keyMap = keyMap;

72 }

73

74 /**

75 * 用于封装随机产生的公钥与私钥

76 */

77 private Map<String, String> keyMap;

78

79

80 public RsaUtil(boolean isKeyBase64) throws NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchProviderException {

81 setKeyMap(generateKeyPair(isKeyBase64));

82 }

83

84 /**

85 * 随机生成密钥对

86 * @param isKeyBase64 密钥base64加密为true,hex为false

87 */

88 private Map<String, String> generateKeyPair(boolean isKeyBase64) throws NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchProviderException {

89 // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象

90 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM);

91 // 初始化密钥对生成器

92 keyPairGen.initialize(KEY_SIZE, new SecureRandom());

93 // 生成一个密钥对,保存在keyPair中

94 KeyPair keyPair = keyPairGen.generateKeyPair();

95 // 得到私钥

96 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

97 // 得到公钥

98 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

99 String publicKeyString = isKeyBase64 ? Base64.getEncoder().encodeToString(publicKey.getEncoded()) : Convert.bytesToHex(publicKey.getEncoded());

100

101 // 得到私钥字符串

102 String privateKeyString = isKeyBase64 ? Base64.getEncoder().encodeToString(privateKey.getEncoded()) : Convert.bytesToHex(privateKey.getEncoded());

103 // 将公钥和私钥保存到Map

104 Map<String, String> map = new HashMap<>(32);

105 //表示公钥

106 map.put("publicKey", publicKeyString);

107 //表示私钥

108 map.put("privateKey", privateKeyString);

109

110 return map;

111 }

112

113 /**

114 * 流程1:RSA公钥加密,再BASE64加密,再base64解密,再RSA私钥解密

115 * 流程2:RSA私钥加密,再BASE64加密,再base64解密,再RSA公钥解密

116 *

117 * @param text 加密字符串/解密字符串

118 * @param secretKey 加密秘钥

119 * @param isPublicKey 公钥/私钥

120 * @param isEncrypt 加密/解密

121 * @param isKeyBase64 密钥base64加密为true,hex为false

122 * @param isTextBase64 密文base64加密为true,hex为false

123 * @param isUrlCode 密文urlencode为true,否则为false

124 * @return 密文/明文

125 * @throws Exception 加密过程中的异常信息

126 */

127 private String enDecrypt(String text, String secretKey, boolean isPublicKey, boolean isEncrypt, boolean isKeyBase64, boolean isTextBase64, boolean isUrlCode) throws Exception {

128 //base64编码的秘钥

129 byte[] decodedKey = isKeyBase64 ? Base64.getDecoder().decode(secretKey.getBytes(ENCODING)) : Convert.hexToByteArray(secretKey);

130 byte[] decodeText;

131 int encodeMode = 0;

132 int max_block = 0;

133 int textLength = 0;

134 Cipher cipher = Cipher.getInstance(PADDING_MODE);

135 UrlCode urlCode = new UrlCode();

136

137

138 if (isEncrypt) {

139 encodeMode = Cipher.ENCRYPT_MODE;

140 max_block = MAX_ENCRYPT_BLOCK;

141 //待加密字符串

142 decodeText = text.getBytes(ENCODING);

143 textLength = text.getBytes(ENCODING).length;

144 } else {

145 encodeMode = Cipher.DECRYPT_MODE;

146 max_block = MAX_DECRYPT_BLOCK;

147 decodeText = isUrlCode ? urlCode.decodeURL(text, UTF_8).getBytes(ENCODING) : text.getBytes(ENCODING);

148 // 注意:byte[]转String,不能 byte[].toString(); 可用new String(byte[])

149 decodeText = isTextBase64 ? Base64.getDecoder().decode(decodeText) : Convert.hexToByteArray(new String(decodeText, ENCODING));

150 textLength = decodeText.length;

151 }

152

153 if (isPublicKey) {

154 cipher.init(encodeMode, (RSAPublicKey) KeyFactory.getInstance(ALGORITHM).generatePublic(new X509EncodedKeySpec(decodedKey)));

155 } else {

156 cipher.init(encodeMode, (RSAPrivateKey) KeyFactory.getInstance(ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(decodedKey)));

157 }

158

159 ByteArrayOutputStream out = new ByteArrayOutputStream();

160 int offSet = 0;

161 byte[] cache;

162 int i = 0;

163 // 对数据分段加密

164 while (textLength - offSet > 0) {

165 if (textLength - offSet > max_block) {

166 cache = cipher.doFinal(decodeText, offSet, max_block);

167 } else {

168 cache = cipher.doFinal(decodeText, offSet, textLength - offSet);

169 }

170 out.write(cache, 0, cache.length);

171 i++;

172 offSet = i * max_block;

173 }

174 byte[] byteText = out.toByteArray();

175 out.close();

176

177 String resultText = out.toString();

178 if (isEncrypt) {

179 resultText = isTextBase64 ? Base64.getEncoder().encodeToString(byteText) : Convert.bytesToHex(byteText);

180 resultText = isUrlCode ? urlCode.encodeURL(resultText, UTF_8) : resultText;

181 }

182

183 return resultText;

184 }

185

186 public String encryptByPublicKey(String plainText, String publicKey, boolean isKeyBase64, boolean isTextBase64, boolean isUrlCode) throws Exception {

187 return enDecrypt(plainText, publicKey, true, true, isKeyBase64, isTextBase64, isUrlCode);

188 }

189

190 public String decryptByPrivateKey(String cipherText, String privateKey, boolean isKeyBase64, boolean isTextBase64, boolean isUrlCode) throws Exception {

191 return enDecrypt(cipherText, privateKey, false, false, isKeyBase64, isTextBase64, isUrlCode);

192 }

193

194 /**

195 * RSA签名

196 *

197 * @param signText 待签名数据

198 * @param privateKey 私钥

199 * @param isKeyBase64 密钥base64加密为true,hex为false

200 * @param isTextBase64 密文base64加密为true,hex为false

201 * @param isUrlCode 密文urlencode为true,否则为false

202 * @return 签名值

203 */

204 public String signByPrivateKey(String signText, String privateKey, boolean isKeyBase64, boolean isTextBase64, boolean isUrlCode) throws Exception {

205 try {

206 KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

207 byte[] decodeKey = isKeyBase64 ? Base64.getDecoder().decode(privateKey) : Convert.hexToByteArray(privateKey);

208

209 PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(decodeKey);

210 //DER input, Integer tag error ,原因密钥错误

211 PrivateKey private_key = (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);

212 Signature signature = Signature.getInstance(SIGN_ALGORITHM);

213 signature.initSign(private_key);

214

215 String sign_text = isTextBase64?Convert.bytesToHexString(Base64.getDecoder().decode(signText.getBytes(ENCODING))):signText;

216 // System.out.println("服务器端:待签名数据:"+sign_text);

217

218 assert sign_text != null;

219 byte[] digestText = genDigest(sign_text,SIGN_ALGORITHM );

220

221 // 生成消息摘要 因客户端签名时参数为16进制, 可以通过加密算法验证是否正确

222 signature.update(Convert.bytesToHexString(digestText).getBytes(ENCODING));

223 // System.out.println("服务器端:摘要数据:"+new String(digestText));

224

225 byte[] signedByte = signature.sign();

226 // System.out.println("服务器端:签名数据:"+Convert.bytesToHexString(signedByte));

227

228 UrlCode urlCode = new UrlCode();

229

230 String signedText = isTextBase64 ? Base64.getEncoder().encodeToString(signedByte) : Convert.bytesToHex(signedByte);

231 signedText = isUrlCode ? urlCode.encodeURL(signedText, UTF_8) : signedText;

232

233 return signedText;

234

235 } catch (Exception e) {

236 throw new UtilException(e.getMessage());

237 }

238 }

239

240

241 /*

242 * 生成消息摘要

243 */

244 public byte[] genDigest(String plainText, String algorithm) throws NoSuchAlgorithmException, UnsupportedEncodingException {

245

246 MessageDigest messageDigest = MessageDigest.getInstance(algorithm.split("w")[0]);

247 // System.out.println("服务器端,哈希算法:"+algorithm.split("w")[0]);

248 byte [] digestText = messageDigest.digest(plainText.getBytes(ENCODING));

249 // System.out.println("服务器端,摘要:"+bytesToHexString(digestText));

250 return digestText;

251 }

252

253 /**

254 * RSA验签名检查

255 *

256 * @param signText 待签名数据

257 * @param signedText 已签名数据

258 * @param publicKey 公钥

259 * @param isKeyBase64 密钥base64加密为true,hex为false

260 * @param isTextBase64 密文base64加密为true,hex为false

261 * @param isUrlCode 密文urlencode为true,否则为false

262 * @return 布尔值

263 */

264 public boolean verifySignPublicKey(String signText, String signedText, String publicKey, boolean isKeyBase64, boolean isTextBase64, boolean isUrlCode) throws Exception {

265 boolean isVerified;

266 try {

267 KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

268 byte[] decodedKey = isKeyBase64 ? Base64.getDecoder().decode(publicKey) : Convert.hexToByteArray(publicKey);

269 PublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));

270 Signature signature = Signature.getInstance(SIGN_ALGORITHM);

271

272 signature.initVerify(pubKey);

273

274 signText = isTextBase64?Convert.bytesToHexString( Base64.getDecoder().decode(signText.getBytes(ENCODING))) :signText;

275 // 生成消息摘要

276 assert signText != null;

277 // System.out.println("验证,待签名数据:"+signText);

278

279 byte[] digestText = genDigest(signText,SIGN_ALGORITHM );

280 // 生成消息摘要

281 signature.update(Convert.bytesToHexString(digestText).getBytes(ENCODING));

282

283 UrlCode urlCode = new UrlCode();

284 String decodeText = isUrlCode ? urlCode.decodeURL(signedText, UTF_8) : signedText;

285 byte[] bytesText = isTextBase64 ? Base64.getDecoder().decode(decodeText) : Convert.hexToByteArray(decodeText);

286

287 //DER input, Integer tag error ,或 DerInputStream.getLength(): lengthTag=111, too big.原因密钥错误

288 isVerified = signature.verify(bytesText);

289

290 } catch (Exception e) {

291 throw new UtilException(e.getMessage());

292 }

293 return isVerified;

294 }

295

296

297 // PKCS#1 与PKCS#8 格式转换

298 // 带头和尾的密钥,去掉头和尾后,再按指定格式增加头和尾

299 public Map<String,String> convertKeyFormat(Map<String,String> mapSource,String keyMode)

300 {

301 Map<String,String> map = removeHeaderAndBottom(mapSource,keyMode);

302 map = formatKey (map,keyMode);

303

304 return map;

305 }

306

307 public Map<String,String> removeHeaderAndBottom (Map<String,String> mapSource,String keyMode)

308 {

309 Map<String,String> map = new HashMap<>();

310 Map<String,String> mapHeaderAndBottom_publicKey = genKeyHeaderAndBottom(keyMode,false);

311 Map<String,String> mapHeaderAndBottom_privateKey = genKeyHeaderAndBottom(keyMode,true);

312

313 String privateKey = mapSource.get("privateKey");

314 String publicKey = mapSource.get("publicKey");

315

316 publicKey = publicKey.replaceAll(mapHeaderAndBottom_publicKey.get("header"),"");

317 publicKey = publicKey.replaceAll(mapHeaderAndBottom_publicKey.get("bottom"),"");

318

319 privateKey=privateKey.replaceAll(mapHeaderAndBottom_privateKey.get("header"),"");

320 privateKey= privateKey.replaceAll(mapHeaderAndBottom_privateKey.get("bottom"),"");

321

322 map.put("publicKey",publicKey);

323 map.put("privateKey",privateKey);

324

325 return map;

326 }

327

328 // 不带头和尾的密钥,按指定格式增加头和尾

329 public Map<String,String> formatKey( Map<String,String> mapSource, String keyMode)

330 {

331 Map<String,String> map = new HashMap<>();

332

333 map.put("publicKey", formatKey(mapSource.get("publicKey"),keyMode,false));

334 map.put("privateKey", formatKey(mapSource.get("privateKey"),keyMode,true));

335

336 return map;

337 }

338

339 // 格式化key,增加头和尾

340 private String formatKey( String keyBody, String keyMode,boolean isPrivateKey )

341 {

342 Map<String,String> map = genKeyHeaderAndBottom(keyMode,isPrivateKey);

343 String keyHeader = map.get("header");

344 String keyBottom =map.get("bottom");

345 String strKey = keyHeader + "\n";

346

347 int nPrivateKeyLen = keyBody.length();

348 char[] status = keyBody.toCharArray();

349 for(int i = 64; i < nPrivateKeyLen; i+=64)

350 {

351 if(status[i] != '\n')

352 {

353 status[i]= '\n';

354 }

355 i++;

356 }

357 strKey += String.valueOf(status);

358 strKey += "\n";

359 strKey += keyBottom;

360 strKey += "\n";

361

362 return strKey;

363 }

364

365 // 按指定格式生成头和尾

366 public Map<String,String> genKeyHeaderAndBottom(String keyMode,boolean isPrivateKey)

367 {

368 Map<String,String> map = new HashMap<>();

369 if (keyMode == "PKCS#1") {

370 if (isPrivateKey) {

371 map.put("header", "-----BEGIN RSA PRIVATE KEY-----");

372 } else {

373 map.put("header", "-----BEGIN RSA PUBLIC KEY-----");

374 }

375 if (isPrivateKey) {

376 map.put("bottom", "-----END RSA PRIVATE KEY-----");

377 } else {

378 map.put("bottom", "-----END RSA PUBLIC KEY-----");

379 }

380 }

381 else if (keyMode == "PKCS#8") {

382 if (isPrivateKey) {

383 map.put("header", "-----BEGIN PRIVATE KEY-----");

384 } else {

385 map.put("header", "-----BEGIN PUBLIC KEY-----");

386 }

387 if (isPrivateKey) {

388 map.put("bottom", "-----END PRIVATE KEY-----");

389 } else {

390 map.put("bottom", "-----END PUBLIC KEY-----");

391 }

392 }

393 return map;

394 }

395 }

View Code

测试使用流程方法

 1  public static void testRSAflow() throws Exception {

2

3 // 测试前后端使用流程

4 // 1、后端生成密钥对,公钥分享给前端,前端获取到服务器给的公钥。

5 // 2、前端用服务器端给的公钥 及算法:RSA/CBC/PKCS1Padding 加密"xhy 我爱你 中国 依芸Yiyun !!!" 生成加密数据。

6 // 3、前端然后生成自己的密钥对,用自己的私钥及算法SHA1withRSA生成摘要签名。

7 // 4、前端把加密数据、自己的公钥与签名一并发给后端。

8 // 3、后端收到加密数据、签名数据、前端的公钥,先用前端公钥、签名数据、算法SHA1withRSA 验签,验签通过后再用后端的私钥、算法:RSA/CBC/PKCS7Padding 解密数据。

9 // 注意:密钥与密文全部base64编码

10

11 RsaUtil rsaUtil = new RsaUtil(true);

12

13 String privateKey_s = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIfKRPRzS0a9Rg1LQizkfIL1ciAMEFs45tl49ERuwIA1kcUrtB1Cjj3bKMLO0Sp7992ECOWVZsE6DZPle3kVYFufIBT4pjR1oJqRs4Z9g5bkwY6p743eGnT1pxri5LNqBdevlKsjqwcfIdOhIqz2BaeM3PT1O52PI9e+U40XEri7AgMBAAECgYAmNYNLqbmP0SiKCxg226AxlXEklWBw2sUSgpdxPhzKtsgqzA5lgVnXC/kfP+TZaIKpgUKjn3OHgZdae2NQAfTXxTcvhNGYSOeJ8VgslQueoJW7ypgQ/IoNy2DeglObAJ3uCgA4F566j6H7IvcllKGmDT/6PUlljxZJpBMfslspgQJBAP19EMRxmV4vYL7o55oR397UEUXn3vO88SPo2gxaPZ/ltzgaHM5R1zALPE1EfPIPqVdGf2hcowr22pC1BG+nlXsCQQCJIq4USfgNmjGwquo5PyksQ9vsYc/OxGBxEqTpVez24eJb7tvoqvbYfpleeEyWgtvzHqnlY24QdONhVVm5zOXBAkAxt7PwM6+3D2fUSe4TA+p60/FHWsEZ4TcSqfsKbTClCfMzp7t6pAamv61mIka3W2cFXShkGbdI0T3xH+/szlu9AkBi3SSgrd7td39hPSaU1MsLBXT0SmO1Te+1NNq8+VxXc+trmZzidPZ2h3ZsG9AjJf4JnM6g9/iuVoZiclS4VVZBAkEAsPkIGRvX4Nj3ljiBjgdJ68JRZC3gK/kXLNeefIeHg6F/4eyg729PlfdD2mvPb8hiszvsT1zvF8gvxGi4lT6B/w==" ;

14 String publicKey_s = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCHykT0c0tGvUYNS0Is5HyC9XIgDBBbOObZePREbsCANZHFK7QdQo492yjCztEqe/fdhAjllWbBOg2T5Xt5FWBbnyAU+KY0daCakbOGfYOW5MGOqe+N3hp09aca4uSzagXXr5SrI6sHHyHToSKs9gWnjNz09TudjyPXvlONFxK4uwIDAQAB";

15 String publicKey_c ="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQPgskvyi9D/IuD0x73M2UOxBH3daAGbxLfUiSraG3cEgZCp7/o1RKM/Uckoplw/DDD665je4wVc0R2zZ8E9LQrrHvvVgddaCvaFZkcIno4EVtHCLldKOFzAIr8ucxCHelV9oGhrcCmeGwYnVTeXOerY9iFi2KDWwF30e2PHRpRQIDAQAB";

16

17 // publicKey_s = rsaUtil.getKeyMap().get("publicKey");

18 // privateKey_s =rsaUtil.getKeyMap().get("privateKey");

19 System.out.println("<--- 1 --->服务器端生成公钥:" +publicKey_s );

20 // System.out.println("<--- 1 --->服务器端生成私钥:"+ privateKey_s);

21 System.out.println("<--- 1 --->服务器端生成私钥,不公开");

22 System.out.println("<--- 2 --->客户端获取到服务器端给定的公钥:"+ publicKey_s);

23 System.out.println("<--- 3 --->客户端用此公钥执行加密,加密原始数据:xhy 我爱你 中国 依芸Yiyun !!!");

24

25 // 客户端用服务器端的公钥生成的密文

26 String cipherText_c ="eCOu/WkaQ8tZHk2u+Y9bh6RKOVMQGsssjnQB5DVlUeDPhjiIybeQSe7JH7fG5FgsucCi6uFwdU7yWzmkJFmMKGnE1pGLReqSaWgecviSTl1P4jjrq84VJvreoeCmcNUCoqxQvmYuMxB/D4rZ+PTuv0B2sQ4Q5fOH6fbqoj3uD5w=";

27 cipherText_c ="MoYui9R3RZ+OYamuTvwAGWy2u8rllBQpjGzTXzje9aUM/KiD5nt8DYf1wna5a7DkBYpZ0CRVNHtOHiHgmrheBkpLuAXdh58eVn2hFLn0xCXqIRk+yEZSrF8fHJ7EBhE00WcyfqOoAM+uum57DFxtvATcEnFiEdkRb32JWkumdIY=";

28 System.out.println("<--- 3 --->客户端生成的加密数据:"+cipherText_c);

29 System.out.println("<--- 4 --->客户端生成自己的公钥:"+ publicKey_c);

30 // System.out.println("<--- 4 --->客户端生成自己的私钥:"+ privateKey_c);

31 System.out.println("<--- 4 --->客户端生成自己的私钥,不公开");

32

33 // 客户端利用自己的私钥生成摘要后进行的签名

34 String signedText_c = "uFy+PqjxdxusV5+a9VR0cvk1XY0+Th8jWBT581irWVEDyzq00xGphQ8KIyApgvPw5+KP1DB/M7tMfd0viUT4w8i4VcyhGmRlk0XNkuRhQDgcWeZ5XKIoJ1ORQ0ecxcAAAAlPwMe2wCbPClXFmhJzypJtS7nKFzE/oeZg7nr91zg=";

35 signedText_c ="reCyRzzxeo1i269BdV5TBrYqiYNyWEmk+i6Oxq/0MJz581tThBikh6/Z+hTZ3vY03UngoXwxB7pZBPW7FUxtwdqS8FcKtlVShaz0ZwU22BHbqFBvCvr4C224HQAdNeVoeHb3o8O/DEjNruUzM1NkweLqayI0unieRYxebvCweTE=";

36 System.out.println("<--- 4 --->客户端利用自己的私钥生成摘要而后签名数据:"+signedText_c);

37 System.out.println("<--- 5 --->客户端发送数据至服务器端,1自己的公钥,2自己的加密数据,3自己的签名数据");

38 System.out.println("<--- 6 --->服务器端接收到来自客户端的数据:1客户端的公钥,2客户端的加密数据,3客户端的签名数据");

39 System.out.println("<--- 6 --->1客户端的公钥:"+publicKey_c);

40 System.out.println("<--- 6 --->2客户端的加密数据:"+cipherText_c);

41 System.out.println("<--- 6 --->2客户端的签名数据:"+signedText_c);

42

43 boolean isPassed = rsaUtil.verifySignPublicKey(cipherText_c, signedText_c, publicKey_c, true,true,false);

44 System.out.println("<--- 7 --->服务器端用自己的公钥进行签名验证,结果:"+isPassed);

45 if (isPassed)

46 {

47 System.out.println("<--- 8 --->服务器端验签成功,开始解密数据...");

48

49 String plainText = "";

50 plainText = rsaUtil.decryptByPrivateKey(cipherText_c,privateKey_s,true,true,false);

51

52 System.out.println("<--- 9 --->服务器端解密数据成功:"+ plainText);

53 }

54

55 /* 测试代码

56 // 服务器端用服务器端的公钥生成的密文

57 String cipherText_s ="";

58 String plainText = "xhy 我爱你 中国 依芸Yiyun !!!";

59 cipherText_s = rsaUtil.encryptByPublicKey(plainText, publicKey_s,true, true,false);

60 System.out.println("服务器端执行加密,公钥加密:"+cipherText_s);

61

62 // 服务器端利用客户端的私钥进行签名

63 String signedText_s = rsaUtil.signByPrivateKey(cipherText_c, privateKey_c,true, true,false);

64 System.out.println("服务器端执行签名,私钥签名:"+signedText_s);

65 */

66

67 /* String privateKey_c = "MIICXAIBAAKBgQDQPgskvyi9D/IuD0x73M2UOxBH3daAGbxLfUiSraG3cEgZCp7/o1RKM/Uckoplw/DDD665je4wVc0R2zZ8E9LQrrHvvVgddaCvaFZkcIno4EVtHCLldKOFzAIr8ucxCHelV9oGhrcCmeGwYnVTeXOerY9iFi2KDWwF30e2PHRpRQIDAQABAoGARuvaf7la9ojnwigTtFuO6Fz1PoSe+SHKrysL/GiGGyNyapTjccz+eAcaA5Ek8WO6K7S7nRZpeKzAGsS92aQmt66BpOqI+JJ2uM+K1HzH5K5rQ4rnaC/Hbd+4zsltVzuLbsICDGSlkpTSKK5YdIkA5YPMXoQek4zoYpUnKT2AxEECQQDoDrjIJ4MllIpc" +

68 "gAWjahga1YrcTIcQPBwG9rfX7zk2nKFZF5rOB6iDHjE9mo9EOD/s7j3Z5eefwVkp" +

69 "hRnbXJp3AkEA5bpMSf8zyBKfMZll3vdtDTDqnsVzOu89RxQYgceyWZ/OcFgvc9hg" +

70 "NYoV/EkGQXcHWL1gPQwWpMRfS8L/DjbNIwJBAL3NBL/Y6YB8TOq5X2M4bHzOOiRT" +

71 "h4j00Su08ctxA8eyNpnrH5fyVZbgw/+SAioXI9oDRp2JWHinKOk3z11HEaMCQDI/" +

72 "qLY60xm9MQMJWaYGmtzayUcHS2glslKcy6t/gbxm3yHluCNvvcOYO6zeUDb7kSjQ" +

73 "638O6NkLdwi8U0vJot8CQHEfumEFZ0LYbz914TZOWe2q0UKOUZaHgQIwoJ3n2yxJ" +

74 "p7Ps3k9t2Of8Tm+HqZYCkSz8henOM8aFCS2GPD8Pkf4=" ;

75 */

76 }

View Code

客户端vue:

工具类,常用加解密算法,enDecrypt.js

  1  /* base64 加解密

2 */

3 export let Base64 = require('js-base64').Base64

4

5 /* md5 加解密

6 */

7 export let crypto = require('crypto');

8 export let md5 = require('js-md5');

9 export let CryptoJS = require('crypto-js');

10 export let MD5 = CryptoJS.MD5;

11 /*

12 *引入jsencrypt实现数据RSA加密

13 */

14 import JSEncrypt from 'jsencrypt';

15 // jsencrypt.js处理长文本数据时报错 Message too long for RSA

16 // encryptlong是基于jsencrypt扩展的长文本分段加解密功能。

17 import Encrypt from "encryptlong";

18 // rsa sign

19 import jsrsasign from 'jsrsasign'

20

21 // Message Digest algorithm 5,信息摘要算法

22 // alglorithm:md5、sha1、sha256

23 export function Md5(plainText, alglorithm, encoding){

24 const hash = crypto.createHash(alglorithm)

25 hash.update(plainText);//加密内容

26 return hash.digest(encoding);//密文

27 }

28

29 //Hash Message Authentication Code,散列消息鉴别码

30 //Secure Hash Algorithm,安全散列算法

31 //alglorithm:md5、sha256、sha1

32 export function HMac(plainText, secretKey,alglorithm, encoding){

33 const hmac= crypto.createHmac(alglorithm, secretKey);

34 const cipherText= hmac.update(plainText);//加密内容

35 return cipherText.digest(encoding);//密文

36 }

37

38 // Data Encryption Standard,数据加密算法

39 // DES/DES3/AES 加密, key与iv长度必须是8的倍数

40 // mode:CryptoJS.mode.CBC、CryptoJS.mode.ECB、CryptoJS.mode.CFB

41 // padding:CryptoJS.pad.ZeroPadding、CryptoJS.pad.Pkcs7、CryptoJS.pad.NoPadding

42 export function encrypt ( algorithm, plainText,key, iv, mode, padding, isTextBase64) {

43 key = key ? key : "abcdefghijklmnop";

44 iv = iv ? iv : "0102030405060708";

45

46 const keyHex = CryptoJS.enc.Utf8.parse(key);

47 const ivHex = CryptoJS.enc.Utf8.parse(iv);

48 const option = { iv:keyHex,mode: mode, padding: padding }

49 let encrypted = null ;

50 if(algorithm === "TripleDES"){

51 encrypted = CryptoJS.TripleDES.encrypt(plainText, keyHex, option)

52 }else if(algorithm === "DES"){

53 encrypted = CryptoJS.DES.encrypt(plainText, keyHex, option)

54 }

55 else if(algorithm === "AES"){

56 encrypted = CryptoJS.AES.encrypt(plainText, keyHex, option)

57 }

58 return isTextBase64?CryptoJS.enc.Base64.stringify(encrypted.ciphertext):encrypted.ciphertext.toString();

59 }

60

61 // DES/DES3/AES解密,key与iv长度必须是8的倍数

62 export function decrypt (algorithm,cipherText,key, iv, mode, padding, isTextBase64) {

63 key = key ? key : "abcdefghijklmnop";

64 iv = iv ? iv : "0102030405060708";

65

66 const keyHex = CryptoJS.enc.Utf8.parse(key);

67 const ivHex = CryptoJS.enc.Utf8.parse(iv);

68 const decryptText = isTextBase64? CryptoJS.enc.Base64.parse(cipherText):cipherText;

69 const textHex = { ciphertext: isTextBase64?decryptText:CryptoJS.enc.Hex.parse(decryptText) }

70 const option = { iv:ivHex,mode: mode, padding: padding }

71 let decrypted = null;

72 if(algorithm === "TripleDES"){

73 decrypted = CryptoJS.TripleDES.decrypt(textHex, keyHex, option);

74 }else if(algorithm === "DES"){

75 decrypted = CryptoJS.DES.decrypt(textHex, keyHex, option);

76 }

77 else if(algorithm === "AES"){

78 decrypted = CryptoJS.AES.decrypt(textHex, keyHex, option);

79 }

80 return decrypted.toString(CryptoJS.enc.Utf8);

81 }

82

83 export function stringToHex(strSource) {

84 if(strSource === "")

85 return "";

86 var hexCharCode = [];

87 for(var i = 0; i < strSource.length; i++) {

88 hexCharCode.push((strSource.charCodeAt(i)).toString(16));

89 }

90 return hexCharCode.join("");

91 }

92

93 export function hexToString(hexCharCodeStr) {

94 var trimedStr = hexCharCodeStr.trim();

95 var len = trimedStr.length;

96 if(len % 2 !== 0) {

97 alert("Illegal Format ASCII Code!");

98 return "";

99 }

100 var curCharCode;

101 var resultStr = [];

102 for(var i = 0; i < len;i = i + 2) {

103 curCharCode = parseInt(trimedStr.substr(i, 2), 16); // ASCII Code Value

104 resultStr.push(String.fromCharCode(curCharCode));

105 }

106 return resultStr.join("");

107 }

108

109 /** RSA 加密过程

110 * (1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。

111 * (2)A传递自己的公钥给B,B用A的公钥对消息进行加密。

112 * (3)A接收到B加密的消息,利用A自己的私钥对消息进行解密。

113 * 在这个过程中,只有2次传递过程,第一次是A传递公钥给B,第二次是B传递加密消息给A,即使都被敌方截获,也没有危险性。

114 * 因为只有A的私钥才能对消息进行解密,防止了消息内容的泄露。

115 * 使用方法

116 * 客户端初始化访问服务器端时,服务器端会生成一对RSA对,及公钥和密钥。

117 * 如果前端只需要将要传给后端的数据进行加密后传输,那么前端可以只要公钥,通过公钥对要传输的参数进行加密后把加密的字符串发给后端,后端取出保存的密码种子或者直接保存的私钥,采用私钥对加密字符串进行解密,得到明文。

118 * 如果前端要获取后端传过来的已经加密后的字符串,并且解密使用,那么前端就需要拿到RSA对立面的私钥进行解密后使用了。

119 * */

120 /* JSEncrypt 公钥加密 padding:pkcs1pad2 */

121 export function RsaJSEncrypt(plainText,publicKey,isKeyBase64,isTextBase64,isURLCode) {

122 const jsencrypt = new JSEncrypt({

123 default_key_size: 1024

124 });

125 // setPublicKey 参数默认需要base64,如果是十六进制编码则需要转换为base64,jsrsasign.b64tohex,jsrsasign.hextob64

126 isKeyBase64?jsencrypt.setPublicKey(publicKey):jsencrypt.setPublicKey( jsrsasign.hextob64(publicKey));

127 // 如果是对象/数组的话,需要先JSON.stringify转换成字符串

128 // 处理中文乱码,服务器端:String result = java.net.URLDecoder.decode(cipherText ,"UTF-8");

129 let cipherText = jsencrypt.encrypt(plainText);

130

131 // 默认加密结果为base64编码

132 cipherText = isTextBase64?cipherText:jsrsasign.b64tohex(cipherText);

133 // +号服务器端不识别,url编码

134 cipherText = isURLCode? encodeURIComponent(cipherText):cipherText;

135

136 return cipherText;

137 }

138

139 /* JSEncrypt 私钥解密 padding:pkcs1pad2 */

140 export function RsaJSDecrypt(cipherText,privateKey,isKeyBase64,isTextBase64,isURLCode) {

141 const jsencrypt = new JSEncrypt({

142 default_key_size: 1024,

143 padding: crypto.constants.RSA_PKCS1_PADDING

144 });

145

146 isKeyBase64?jsencrypt.setPrivateKey(privateKey):jsencrypt.setPrivateKey(jsrsasign.hextob64(privateKey));

147

148 cipherText = isURLCode?decodeURIComponent(cipherText):cipherText;

149 cipherText = isTextBase64?cipherText:jsrsasign.b64tohex(cipherText);

150

151 return jsencrypt.decrypt(cipherText);

152 }

153

154 /* 长文本分段加密 */

155 export function RsaEncrypt(plainText,publicKey,isKeyBase64,isTextBase64,isURLCode) {

156 const encryptor = new Encrypt({

157 default_key_size: 1024,

158 padding: crypto.constants.RSA_PKCS1_PADDING

159 });

160 if (isKeyBase64) {

161 encryptor.setPublicKey(publicKey)

162 }

163 else {

164 encryptor.setPublicKey(jsrsasign.hextob64(publicKey));

165 }

166

167 // 处理中文乱码,服务器端:String result = java.net.URLDecoder.decode(cipherText ,"UTF-8");

168

169 let cipherText = encryptor.encryptLong(plainText);

170

171 cipherText = isTextBase64?cipherText:jsrsasign.hextob64(cipherText);

172 // +号服务器端不识别,url编码

173 cipherText = isURLCode? encodeURIComponent(cipherText):cipherText;

174

175 return cipherText;

176 }

177

178 /* 长文本分段解密 */

179 export function RsaDecrypt(cipherText,privateKey,isKeyBase64,isTextBase64,isURLCode) {

180 const encryptor = new Encrypt({

181 default_key_size: 1024,

182 padding: crypto.constants.RSA_PKCS1_PADDING

183 })

184

185 if (isKeyBase64){

186 encryptor.setPrivateKey(privateKey)

187 }

188 else{

189 encryptor.setPrivateKey(jsrsasign.hextob64(privateKey));

190 }

191 cipherText = isURLCode?decodeURIComponent(cipherText):cipherText;

192 cipherText = isTextBase64?cipherText:jsrsasign.b64tohex(cipherText);

193

194 return encryptor.decryptLong(cipherText);

195 }

196

197 // 获取签名 privateKey

198 export function RsaSign(plainText,privateKey,format_key, algorithm,isKeyBase64,isTextBase64,isURLCode)

199 {

200 // 生成签名对象

201 let sign = genSign(isKeyBase64?privateKey:jsrsasign.hextob64(privateKey),format_key, algorithm);

202 plainText = isTextBase64?jsrsasign.b64tohex(plainText):plainText;

203 // console.log("待签名前数据:"+plainText);

204 let plain_Text = genDigest(plainText,algorithm);

205

206 // console.log("待签名摘要数据:"+plain_Text);

207 sign.updateString(plain_Text);

208

209 // 默认签名数据为十六进制数据

210 let signedText = isTextBase64?jsrsasign.hextob64(sign.sign()):sign.sign();

211

212 // console.log("生成签名数据:"+sign.sign());

213 // +号服务器端不识别,url编码

214 signedText = isURLCode? encodeURIComponent(signedText):signedText;

215

216 return signedText;

217 }

218

219 // 验证签名 publicKey_s 服务器端的公钥

220 // alglorithm: SHA1withRSA、MD5withRSA、SHA256withRSA、 SHA384withRSA、SHA512withRSA、RIPEMD160withRSA

221 // format_key: PKCS#1、PKCS#5、PKCS#8

222 /*

223 * PKCS#1:定义RSA公开密钥算法加密和签名机制,主要用于组织PKCS#7中所描述的数字签名和数字信封。

224 * PKCS#3:定义Diffie-Hellman密钥交换协议。

225 * PKCS#5:描述一种利用从口令派生出来的安全密钥加密字符串的方法。使用MD2或MD5 从口令中派生密钥,并采用DES-CBC模式加密。主要用于加密从一个计算机传送到另一个计算机的私人密钥,不能用于加密消息[24]。

226 * PKCS#6:描述了公钥证书的标准语法,主要描述X.509证书的扩展格式。

227 * PKCS#7:定义一种通用的消息语法,包括数字签名和加密等用于增强的加密机制,PKCS#7与PEM兼容,所以不需其他密码操作,就可以将加密的消息转换成PEM消息[26]。

228 * PKCS#8:描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等。

229 * PKCS#9:定义一些用于PKCS#6证书扩展、PKCS#7数字签名和PKCS#8私钥加密信息的属性类型。

230 * PKCS#10:描述证书请求语法。

231 * PKCS#11:称为Cyptoki,定义了一套独立于技术的程序设计接口,用于智能卡和PCMCIA卡之类的加密设备。

232 * PKCS#12:描述个人信息交换语法标准。描述了将用户公钥、私钥、证书和其他相关信息打包的语法。

233 * PKCS#13:椭圆曲线密码体制标准。

234 * PKCS#14:伪随机数生成标准。

235 * PKCS#15:密码令牌信息格式标准。

236 */

237 export function RsaVerifySign(plainText,signedText,publicKey,format_key, algorithm,isKeyBase64,isTextBase64,isURLCode)

238 {

239 // 生成签名

240 let verifySign = genSign(isKeyBase64?publicKey:jsrsasign.hextob64(publicKey),format_key, algorithm);

241 plainText = isTextBase64?jsrsasign.b64tohex(plainText):plainText;

242 // 根据明文生成摘要

243 let digestText = genDigest(plainText,algorithm);

244

245 verifySign.updateString(digestText);

246

247 signedText = isURLCode?decodeURIComponent(signedText):signedText;

248 signedText = isTextBase64?jsrsasign.b64tohex(signedText):signedText;

249

250 return verifySign.verify(signedText);

251 }

252

253 // 根据明文生成摘要

254 //SHA1withRSA、MD5withRSA、SHA256withRSA、 SHA384withRSA、SHA512withRSA、RIPEMD160withRSA

255 export function genDigest(plainText,algorithm ){

256 let option = { "alg": algorithm.split('w')[0], "prov":"cryptojs/jsrsa", }

257 // console.log("算法:"+algorithm.split('w')[0]);

258 let text = new jsrsasign.KJUR.crypto.MessageDigest(option); // 摘要

259 text.updateString(plainText);

260

261 let digestText = text.digest();

262 // console.log("摘要:"+digestText);

263 return digestText;

264 }

265

266 /* 生成rsa签名对象

267 * */

268 export function genSign(RsaKey,format_key, algorithm)

269 {

270 // 密钥要写开头和结束

271 // var private_key = '-----BEGIN PRIVATE KEY-----' + privateKey_s + '-----END PRIVATE KEY-----'

272 // 读取解析pem格式的秘钥, 生成秘钥实例 (RSAKey)

273 let rsaKey = new jsrsasign.RSAKey();

274 if (format_key === "PKCS#1" || format_key === "PKCS#5"|| format_key === "PKCS#7"|| format_key === "PKCS#8") {

275 rsaKey = jsrsasign.KEYUTIL.getKey(RsaKey);

276 // rsaSign.readPrivateKeyFromPEMString(privateKey_s);

277 }

278

279 let option= {

280 "alg":algorithm,

281 "prov":"cryptojs/jsrsa",

282 "prvkeypem": rsaKey

283 };

284

285 let sign = new jsrsasign.KJUR.crypto.Signature(option);

286 sign.init(rsaKey);

287

288 return sign;

289 }

前端使用代码流程:

 1 // 测试前后端使用流程

2 // 1、后端生成密钥对,公钥分享给前端,前端获取到服务器给的公钥。

3 // 2、前端用服务器端给的公钥 及算法:RSA/CBC/PKCS1Padding 加密"xhy 我爱你 中国 依芸Yiyun !!!" 生成加密数据。

4 // 3、前端然后生成自己的密钥对,用自己的私钥及算法SHA1withRSA生成摘要签名。

5 // 4、前端把加密数据、自己的公钥与签名一并发给后端。

6 // 3、后端收到加密数据、签名数据、前端的公钥,先用前端公钥、签名数据、算法SHA1withRSA 验签,验签通过后再用后端的私钥、算法:RSA/CBC/PKCS7Padding 解密数据。

7 // 注意:密钥与密文全部base64编码

8

9 let plainText = "xhy 我爱你 中国 依芸Yiyun !!!";

10

11 let privateKey_c = "-----BEGIN RSA PRIVATE KEY-----" +

12 "MIICXAIBAAKBgQDQPgskvyi9D/IuD0x73M2UOxBH3daAGbxLfUiSraG3cEgZCp7/" +

13 "o1RKM/Uckoplw/DDD665je4wVc0R2zZ8E9LQrrHvvVgddaCvaFZkcIno4EVtHCLl" +

14 "dKOFzAIr8ucxCHelV9oGhrcCmeGwYnVTeXOerY9iFi2KDWwF30e2PHRpRQIDAQAB" +

15 "AoGARuvaf7la9ojnwigTtFuO6Fz1PoSe+SHKrysL/GiGGyNyapTjccz+eAcaA5Ek" +

16 "8WO6K7S7nRZpeKzAGsS92aQmt66BpOqI+JJ2uM+K1HzH5K5rQ4rnaC/Hbd+4zslt" +

17 "VzuLbsICDGSlkpTSKK5YdIkA5YPMXoQek4zoYpUnKT2AxEECQQDoDrjIJ4MllIpc" +

18 "gAWjahga1YrcTIcQPBwG9rfX7zk2nKFZF5rOB6iDHjE9mo9EOD/s7j3Z5eefwVkp" +

19 "hRnbXJp3AkEA5bpMSf8zyBKfMZll3vdtDTDqnsVzOu89RxQYgceyWZ/OcFgvc9hg" +

20 "NYoV/EkGQXcHWL1gPQwWpMRfS8L/DjbNIwJBAL3NBL/Y6YB8TOq5X2M4bHzOOiRT" +

21 "h4j00Su08ctxA8eyNpnrH5fyVZbgw/+SAioXI9oDRp2JWHinKOk3z11HEaMCQDI/" +

22 "qLY60xm9MQMJWaYGmtzayUcHS2glslKcy6t/gbxm3yHluCNvvcOYO6zeUDb7kSjQ" +

23 "638O6NkLdwi8U0vJot8CQHEfumEFZ0LYbz914TZOWe2q0UKOUZaHgQIwoJ3n2yxJ" +

24 "p7Ps3k9t2Of8Tm+HqZYCkSz8henOM8aFCS2GPD8Pkf4=" +

25 "-----END RSA PRIVATE KEY-----";

26

27 let publicKey_c ="-----BEGIN PUBLIC KEY-----" +

28 "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQPgskvyi9D/IuD0x73M2UOxBH" +

29 "3daAGbxLfUiSraG3cEgZCp7/o1RKM/Uckoplw/DDD665je4wVc0R2zZ8E9LQrrHv" +

30 "vVgddaCvaFZkcIno4EVtHCLldKOFzAIr8ucxCHelV9oGhrcCmeGwYnVTeXOerY9i" +

31 "Fi2KDWwF30e2PHRpRQIDAQAB" +

32 "-----END PUBLIC KEY-----";

33

34 let publicKey_s = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCHykT0c0tGvUYNS0Is5HyC9XIgDBBbOObZePREbsCANZHFK7QdQo492yjCztEqe/fdhAjllWbBOg2T5Xt5FWBbnyAU+KY0daCakbOGfYOW5MGOqe+N3hp09aca4uSzagXXr5SrI6sHHyHToSKs9gWnjNz09TudjyPXvlONFxK4uwIDAQAB";

35

36 console.log("<--- 2 --->客户端获取到服务器端给定的公钥:"+ publicKey_s);

37

38 let cipherText_c =this.$RsaEncrypt(plainText,publicKey_s,true,true,false);

39 console.log("<--- 3 --->客户端利用服务器端的公钥加密数据,生成密文,base64编码输出\n"+cipherText_c);

40 // 记录 cipherText_c = "eCOu/WkaQ8tZHk2u+Y9bh6RKOVMQGsssjnQB5DVlUeDPhjiIybeQSe7JH7fG5FgsucCi6uFwdU7yWzmkJFmMKGnE1pGLReqSaWgecviSTl1P4jjrq84VJvreoeCmcNUCoqxQvmYuMxB/D4rZ+PTuv0B2sQ4Q5fOH6fbqoj3uD5w=";

41

42 let signedText_c = this.$RsaSign(cipherText_c,privateKey_c,"PKCS#8","SHA1withRSA",true,

43 true,false);

44 console.log("<--- 4 --->客户端利用自己生成的私钥签名数据,生成摘要与签名\n"+signedText_c);

45 console.log("<--- 4 --->客户端生成自己的公钥\n"+publicKey_c);

46 console.log("<--- 5 --->客户端发送数据至服务器端,1客户端的公钥,2客户端的加密数据,3客户端的签名数据\n");

47 // 记录 signedText_c = "uFy+PqjxdxusV5+a9VR0cvk1XY0+Th8jWBT581irWVEDyzq00xGphQ8KIyApgvPw5+KP1DB/M7tMfd0viUT4w8i4VcyhGmRlk0XNkuRhQDgcWeZ5XKIoJ1ORQ0ecxcAAAAlPwMe2wCbPClXFmhJzypJtS7nKFzE/oeZg7nr91zg=";

48 // 注意:加密密文与签名都是唯一的,不会变化。

49 // 注意:vue 端密钥都要带头。

50 // 注意:vue端及java端函数参数要求是什么类型及何进制。搞明白哪里用base64,哪里2进制,哪里16进制。

51 // 重点还是要了解点原理,比如sha1withrsa,先经过sha1算法,知道aaa,哈希后的密文16进制是:7e240de74fb1ed08fa08d38063f6a6a91462a815,对比自己的程序有没有算错。

52 // 利用一些在线测试工具帮忙验证自己的程序过程。http://www.metools.info/code/c82.html ; 同时知道如何查引入的类库各api的官网,了解如何使用各函数。

53 // 不然遇到莫名奇妙的错误无从解决。报错的地方不一定是程序实际错误的地方。了解查错的方式有:打庄、debug.

54

55 /* 仅供测试使用,加密数据及验签

56 let privateKey_s = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIfKRPRzS0a9Rg1LQizkfIL1ciAMEFs45tl49ERuwIA1kcUrtB1Cjj3bKMLO0Sp7992ECOWVZsE6DZPle3kVYFufIBT4pjR1oJqRs4Z9g5bkwY6p743eGnT1pxri5LNqBdevlKsjqwcfIdOhIqz2BaeM3PT1O52PI9e+U40XEri7AgMBAAECgYAmNYNLqbmP0SiKCxg226AxlXEklWBw2sUSgpdxPhzKtsgqzA5lgVnXC/kfP+TZaIKpgUKjn3OHgZdae2NQAfTXxTcvhNGYSOeJ8VgslQueoJW7ypgQ/IoNy2DeglObAJ3uCgA4F566j6H7IvcllKGmDT/6PUlljxZJpBMfslspgQJBAP19EMRxmV4vYL7o55oR397UEUXn3vO88SPo2gxaPZ/ltzgaHM5R1zALPE1EfPIPqVdGf2hcowr22pC1BG+nlXsCQQCJIq4USfgNmjGwquo5PyksQ9vsYc/OxGBxEqTpVez24eJb7tvoqvbYfpleeEyWgtvzHqnlY24QdONhVVm5zOXBAkAxt7PwM6+3D2fUSe4TA+p60/FHWsEZ4TcSqfsKbTClCfMzp7t6pAamv61mIka3W2cFXShkGbdI0T3xH+/szlu9AkBi3SSgrd7td39hPSaU1MsLBXT0SmO1Te+1NNq8+VxXc+trmZzidPZ2h3ZsG9AjJf4JnM6g9/iuVoZiclS4VVZBAkEAsPkIGRvX4Nj3ljiBjgdJ68JRZC3gK/kXLNeefIeHg6F/4eyg729PlfdD2mvPb8hiszvsT1zvF8gvxGi4lT6B/w==" ;

57

58 console.log("RSAVerifySign_pubK="+this.$RsaVerifySign(cipherText_c, signedText_c,

59 publicKey_c,"PKCS#8","SHA1withRSA",true,true,false));

60

61 plainText = "";

62 plainText = this.$RsaDecrypt(cipherText_c, privateKey_s,true,true,false)

63 console.log("RSADe_priK="+plainText);

64 */

测试结果截图说明

服务器:

  客户端:

以上是 前后端java+vue 实现rsa 加解密与摘要签名算法 的全部内容, 来源链接: utcz.com/z/376269.html

回到顶部