@@ -333,4 +333,194 @@ public class AESDemo {
333333 }
334334}
335335
336+ ` ` `
337+
338+ ## 非对称加密
339+
340+ ### 1 . 对称加密的弊端
341+
342+ - 秘钥分发困难
343+
344+ - 可以通过非对称加密完成秘钥的分发
345+
346+ > https
347+ >
348+ > Alice 和 Bob 通信, Alice 给bob发送数据, 使用对称加密的方式
349+ >
350+ > 1 . 生成一个非对称的秘钥对, bob生成
351+ > 2 . bob将公钥发送给alice
352+ > 3 . alice生成一个用于对称加密的秘钥
353+ > 4 . alice使用bob的公钥就对称加密的秘钥进行加密, 并且发送给bob
354+ > 5 . bob使用私钥就数据解密, 得到对称加密的秘钥
355+ > 6 . 通信的双方使用写好的秘钥进行对称加密数据加密
356+
357+ ### 2 . 非对称加密的秘钥
358+
359+ - 不存在秘钥分发困难的问题
360+
361+ #### 2.1 场景分析
362+
363+ 数据对谁更重要, 谁就拿私钥
364+
365+ - 直观上看: 私钥比公钥长
366+ - 使用第三方工具生成密钥对: 公钥文件xxx.pub xxx
367+
368+ > 1 . 通信流程, 信息加密 (A写数据, 发送给B, 信息只允许B读)
369+ >
370+ > A : 公钥
371+ >
372+ > B : 私钥
373+ >
374+ > 2 . 登录认证 (客户端要登录, 连接服务器, 向服务器请求个人数据)
375+ >
376+ > 客户端: 私钥
377+ >
378+ > 服务器: 公钥
379+ >
380+ > 3 . 数字签名(表明信息没有受到伪造,确实是信息拥有者发出来的,附在信息原文的后面)
381+ >
382+ > - 发送信息的人: 私钥
383+ > - 收到信息的人: 公钥
384+ >
385+ > 4 . 网银U盾
386+ >
387+ > - 个人: 私钥
388+ > - 银行拿公钥
389+
390+ ### 3 . 使用RSA非对称加密通信流程
391+
392+ > 要求: Alice 给 bob发送数据, 保证数据信息只有bob能看到
393+
394+ ### 4 . 生成RSA的秘钥对
395+ #### 4.1 一些概念
396+
397+ 1 . x509证书规范、pem、base64
398+ - pem编码规范 - 数据加密
399+ - base64 - 对数据编码, 可逆
400+ - 不管原始数据是什么, 将原始数据使用64 个字符来替代
401+ - a-z A -Z 0 -9 + /
402+ 2 . ASN .1 抽象语法标记
403+ 3 . PKCS1 标准
404+
405+ ### 5 . 常见算法
406+
407+ > RSA
408+
409+ > ECC (java需要借助第三方库实现加密解密,我将在另外一个项目中用go 实现)
410+
411+ ###6 RSA 示例代码如下
412+ - 注意:经测试在后端使用Cipher.getInstance (“RSA”)加密,在移动端获取解密的Cipher类时要使用Cipher.getInstance (“RSA/ECB/PKCS1Padding”)
413+
414+ - 移动端核心代码
415+ ` ` ` $java
416+ //后端用私钥加密过的数据
417+ String eText = "ETLPedgx7vR9E9JGNIj4pLhvurcOM26oo4RgJhmeF5RvDXVdl3qQ+5H6hmUx3dV2K8jPxi5aKSVs1xnjuMgSfK32fjrqzYBULFaBCmnN1HbpcwYFNMA3enWiVwT3TAWFKA9ReJ2DWh0lkCzaHruOmcWCY3f2tjuEE9X9L0DN7m5R9iy2qgEEDPgfzImYYl8wltYdudryz2fQ7UNGdIUPc75EMqdvHEUrxIi5A7cM0BDGQI2aXD+39ijQCOVBtai/9ohF7YXtGmbsocPBKarhe8qpVIcvXza6fBbOWxBC6Z68uRGcljTVkhvNjWrEmRuu5pc3C41bx4OK9FD8kPgITg==";
418+ //后端给的公钥
419+ String pkey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmpz9g5IX3ElRtXFo2+9nwD4+amqhEH4Rz1FI2cXeSiQeLPfdCoSsflLovdJ21NxvcKGw9IvmjWkLESCVU/pxDeP2UkVXFAjC2KhZvoQO4v0x4Yn3/55bAAQ9O3qoGatjPlDbzr1CEAi+ZA7NY1Oz2TtOSq8Odc7wc3Sq6U1gZBf87w5jq0GwQwgLrQjaVf5oTgKmavyf6g8Uq8U0QnktXCJpJUsSSZdeWTwAhtKk+MDkd5VRHIynLklOgeAhjG7xzEAad/Q32qLGcCwY+ySiZWLZ5q5uZAys4rj98LiwV6zLyk8CYYclUDUtBPLLXDRN8DUEe4uKAucFC4IlkrXQ0wIDAQAB";
420+ //获取公钥对象
421+ KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
422+ X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(pkey, Base64.DEFAULT));
423+ PublicKey publicKey = keyFactory.generatePublic(spec);
424+ //指定解密algorithm = "RSA/ECB/PKCS1Padding"; Cipher cipher = Cipher.getInstance(algorithm);
425+ algorithm = "RSA/ECB/PKCS1Padding";
426+ String decrypt = RSADemo.RSADecrypt(algorithm, publicKey, eText, 256);
427+ System.out.println("decript###" + decrypt + "###");
428+ ` ` `
429+
430+ - 后端代码
431+ ` ` ` java
432+ public class RSADemo {
433+ private static int MAX_ENCRIPT_SIZE = 200;
434+
435+ public static void main(String[] args) throws Exception {
436+ String algorithm = "RSA";
437+ String input = "frank";
438+ // generateKeys(algorithm, "test.pri", "test.pub");
439+
440+ PrivateKey privateKey = getPrivateKey("test.pri", algorithm);
441+ PublicKey publicKey = getPublicKey("test.pub", algorithm);
442+
443+ String encryptData = RSAEncrypt(algorithm, privateKey, input, MAX_ENCRIPT_SIZE);
444+ System.out.println("encryptData=" + encryptData);
445+ String decryptData = RSADecrypt(algorithm, publicKey, encryptData, 256);
446+ System.out.println("decryptData=" + decryptData);
447+
448+ }
449+
450+ public static PrivateKey getPrivateKey(String priPath, String algorithm) throws Exception {
451+ String privateKeyString = FileUtils.readFileToString(new File(priPath), Charset.defaultCharset());
452+ KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
453+ PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyString));
454+ return keyFactory.generatePrivate(spec);
455+ }
456+
457+ public static PublicKey getPublicKey(String pubPath, String algorithm) throws Exception {
458+ String publicKeyString = FileUtils.readFileToString(new File(pubPath), Charset.defaultCharset());
459+ KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
460+ X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(publicKeyString));
461+ return keyFactory.generatePublic(spec);
462+ }
463+
464+ public static void generateKeys(String algorithm, String priPath, String pubPath) throws Exception {
465+ // 获取密钥对生成器
466+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
467+ // 获取密钥对
468+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
469+ // 获取公私钥
470+ PrivateKey privateKey = keyPair.getPrivate();
471+ PublicKey publicKey = keyPair.getPublic();
472+ // 获取公私钥的字节数组
473+ byte[] privateKeyEncoded = privateKey.getEncoded();
474+ byte[] publicKeyEncoded = publicKey.getEncoded();
475+ // 对公私钥进行Base64的编码
476+ String privateKeyString = Base64.encode(privateKeyEncoded);
477+ String publicKeyString = Base64.encode(publicKeyEncoded);
478+
479+ FileUtils.writeStringToFile(new File(priPath), privateKeyString, Charset.defaultCharset());
480+ FileUtils.writeStringToFile(new File(pubPath), publicKeyString, Charset.defaultCharset());
481+ }
482+
483+ public static String RSAEncrypt(String algorithm, Key key, String input, int maxEncryptSize) throws Exception {
484+ Cipher cipher = Cipher.getInstance(algorithm);
485+ cipher.init(Cipher.ENCRYPT_MODE, key);
486+ byte[] data = input.getBytes();
487+ int total = data.length;
488+ int offset = 0;
489+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
490+ byte[] bytes;
491+ while (total - offset > 0) {
492+ if (total - offset >= maxEncryptSize) {
493+ bytes = cipher.doFinal(data, offset, maxEncryptSize);
494+ offset += maxEncryptSize;
495+ } else {
496+ bytes = cipher.doFinal(data, offset, total - offset);
497+ offset = total;
498+ }
499+ baos.write(bytes);
500+ }
501+ return Base64.encode(baos.toByteArray());
502+ }
503+
504+ public static String RSADecrypt(String algorithm, Key key, String input, int maxEncryptSize) throws Exception {
505+ Cipher cipher = Cipher.getInstance(algorithm);
506+ cipher.init(Cipher.DECRYPT_MODE, key);
507+ byte[] data = Base64.decode(input);
508+ int total = data.length;
509+ int offset = 0;
510+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
511+ byte[] bytes;
512+ while (total - offset > 0) {
513+ if (total - offset >= maxEncryptSize) {
514+ bytes = cipher.doFinal(data, offset, maxEncryptSize);
515+ offset += maxEncryptSize;
516+ } else {
517+ bytes = cipher.doFinal(data, offset, total - offset);
518+ offset = total;
519+ }
520+ baos.write(bytes);
521+ }
522+ return baos.toString();
523+ }
524+
525+ }
336526` ` `
0 commit comments