Arno's Blog

Simplicity is prerequisite for reliability.


  • 首页

  • 归档

  • 标签

[JavaWeb] 接入微信公众号(一)

发表于 2016-07-22

微信公众号

相信大家对微信公众号都不陌生,本文就从开发者角度,简单说说目前微信公众号的状况。

阅读全文 »

[JavaWeb] Spring 集成 Apache Shiro 安全框架

发表于 2016-07-14

Apache Shiro 简介

Apache Shiro 是 Java 的一个开源安全框架,提供身份验证、授权、密码学和会话管理。

阅读全文 »

[JavaWeb] 集成 MyBatis Generator 以及 Generator 分页插件

发表于 2016-06-30

MyBatis Generator

MyBatis 有一个非常棒的工具叫 MyBatis Generator,是一个代码生成器。能根据数据库里面的表生成:

  • 模型类
  • Example 类(动态查询、更新和删除的类)
  • Dao 接口
  • 兼容 SQL 映射 XML 文件
  • …等等
阅读全文 »

[JavaWeb] 集成通用 Mapper 与 分页插件PageHelper

发表于 2016-06-30

MyBatis 工具

这次介绍两个 Mybatis 的两个工具:通用 Mapper 与 分页插件PageHelper

都是 Github 上面的 abel533 作者写的

阅读全文 »

Spring + SpringMVC + MyBatis 集成(二)

发表于 2016-06-15

前言

继续进行整合

阅读全文 »

Spring + SpringMVC + MyBatis 集成

发表于 2016-06-08

SSM框架

现在 Java Web 开发中比较热门的框架组合就是 SSM(Spring + SpringMVC + MyBatis)了。使用框架的好处不言而喻,节约了我们的开发时间,框架强制使用公共的约定,团队配合更密切。

使用框架便利的同时,需要学习其中的思想。对提高我们的编程思想很有帮助。可以先实践,再思想,实践出真知!

阅读全文 »

[JAVA]线程与进程总结(二)

发表于 2016-06-03

基本概念

先解释一些名词和基本概念,后续代码演示

原子性

原子是世界上的最小单位,具有不可分割性。

通俗的解释:
CUP 是一条一条指令执行,假设“读”、“写”是两条指令,如果在多线程并发中使用“读写”,那么可能会出现问题。

原子性则是一条指令完成“读写”操作。

阅读全文 »

[JAVA]线程与进程总结(一)

发表于 2016-05-27

前言

在操作系统中有两个概念叫进程(process)和线程(thread),这两个概念,比较抽象,涉及的知识非常多。鉴于篇幅本文只能从一些角度来解释。

阅读全文 »

Spring Boot 微框架

发表于 2016-05-08

Spring Boot 介绍

Spring 框架非常好用,但是会有大量的 XML 配置文件以及复杂的 Bean 依赖关系。而 Spring Boot 就是为此诞生的!

Spring Boot 则采用了“约定优先配置” (convention over configuration)的思想来摆脱 Spring 框架中各类繁复纷杂的配置。

Spring Boot 使开发独立的,产品级别的基于 Spring 的应用变得非常简单,你只需 “just run” 。 我们为 Spring 平台及第三方库提供开箱即用的设置,这样你就可以有条不紊地开始。多数 Spring Boot 应用需要很少的 Spring 配置。

阅读全文 »

对称加密与非对称加密的一些基础知识

发表于 2016-04-15

密码学常用术语

  • 明文:待加密信息
  • 密文:经过加密后的明文
  • 加密:明文转为密文的过程
  • 加密算法:明文转密文的转换算法
  • 加密密钥:通过加密算法进行加密操作用的密钥。
  • 解密:将密文转为明文的过程。
  • 解密算法:密文转为明文的过程。
  • 解密密钥:铜管解密算法进行解密操作用的密钥

通俗而言

  • 可以把“加密”和“解密”理解为某种【互逆的】数学运算。就好比“加法和减法”互为逆运算、“乘法和除法”互为逆运算。
  • “加密”的过程,就是把“明文”变成“密文”的过程;反之,“解密”的过程,就是把“密文”变为“明文”。在这两个过程中,都需要一个关键的东东——叫做“密钥”——来参与数学运算

对称密钥加密

对称密钥加密(英语:Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。实务上,这组密钥成为在两个或多个成员间的共同秘密,以便维持专属的通讯联系

通俗的解释

比如带密码 zip 的压缩包,每次都是同一个密码,加密和解密都是用一个秘密,那么这样的情况可以理解成对称加密。

常见的对称加密算法

常见的对称加密算法有 DES、3DES、AES、Blowfish、IDEA、RC5、RC6、Base64

对称加密的速度比公钥加密快很多,在很多场合都需要对称加密。

代码实现 Base64 加密和解密

先通过 Maven 引入 jar 包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!--加密解密 jar-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-ext-jdk15on</artifactId>
<version>1.54</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.54</version>
</dependency>

代码实现

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
package com.doity.encodeanddecode;


import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import org.apache.commons.codec.binary.Base64;

import java.io.IOException;



/**
* Created by Arno on 2016/5/13/013.
* <p/>
* 算法实现
* JDK
* Commons Codec
* Bouncy Castle
*/


public class Base64Demo {

private static String qiji = "Hi,I'm ARNO";

public static void main(String[] args) {
System.out.println("原始字符串:" + qiji);
System.out.println();
jdkBase64();
System.out.println();
commonsCodeBase64();
System.out.println();
bouncyCastleBase64();
}

public static void jdkBase64() {
try {
System.out.println("使用 JDK 实现 Base64 加密解密");
BASE64Encoder base64Encoder = new BASE64Encoder();
String encode = base64Encoder.encode(qiji.getBytes());
System.out.println("加密:" + encode);
BASE64Decoder base64Decoder = new BASE64Decoder();
System.out.println("解密:" + new String(base64Decoder.decodeBuffer(encode)));
} catch (IOException e) {
e.printStackTrace();
}
}

public static void commonsCodeBase64() {
System.out.println("使用 Commons Codec 实现 Base64 加密解密");
byte[] encodeBytes = Base64.encodeBase64(qiji.getBytes());
System.out.println("加密:" + new String(encodeBytes));

byte[] decodeBytes = Base64.decodeBase64(encodeBytes);
System.out.println("解密:" + new String(decodeBytes));
}

public static void bouncyCastleBase64() {
System.out.println("使用 Bouncy Castle 实现 Base64 加密解密");
byte[] encodeBytes = org.bouncycastle.util.encoders.Base64.encode(qiji.getBytes());
System.out.println("加密:" + new String(encodeBytes));
byte[] decodeBytes = org.bouncycastle.util.encoders.Base64.decode(encodeBytes);
System.out.println("解密:" + new String(decodeBytes));
}
}

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
原始字符串:Hi,I'm ARNO

使用 JDK 实现 Base64 加密解密
加密:SGksSSdtIEFSTk8=
解密:Hi,I'm ARNO

使用 Commons Codec 实现 Base64 加密解密
加密:SGksSSdtIEFSTk8=
解密:Hi,I'm ARNO

使用 Bouncy Castle 实现 Base64 加密解密
Disconnected from the target VM, address: '127.0.0.1:56730', transport: 'socket'
加密:SGksSSdtIEFSTk8=
解密:Hi,I'm ARNO

使用场景

对称加密算法——AES

非对称加密

公开密钥加密(英语:public-key cryptography,又译为公开密钥加密),也称为非对称加密(asymmetric cryptography),一种密码学算法类型,在这种密码学方法中,需要一对密钥,一个是私人密钥,另一个则是公开密钥。这两个密钥是数学相关,用某用户密钥加密后所得的信息,只能用该用户的解密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个的秘密性质。称公开的密钥为公钥;不公开的密钥为私钥。

常见的公钥加密算法

RSA、ElGamal、背包算法、Rabin(RSA的特例)、迪菲-赫尔曼密钥交换协议中的公钥加密算法、椭圆曲线加密算法(英语:Elliptic Curve Cryptography, ECC)。

优点

与对称密钥加密相比,优点在于无需共享的通用密钥,解密的私钥不发往任何用户。即使公钥在网上被截获,如果没有与其匹配的私钥,也无法解密,所截获的公钥是没有任何用处的。

通俗的解释

加密时用一个密钥、解密时用另外一个密钥。

代码实现

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
package com.doity.encodeanddecode;

import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;


/**
* Created by HiArno on 2016/5/14.
*/

public class RSADemo {

private static String qiji = "Hi,I'm ARNO";

public static void main(String[] args) {
jdkRSA();
}

public static void jdkRSA(){
try {
// 初始化密钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
System.out.println("创建共钥成功!");
System.out.println("Public Key: " + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
System.out.println("创建私钥成功!");
System.out.println("Private Key: " + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
System.out.println("公钥的长度比较短!!!据说是为了方便保存");
System.out.println();


// 私钥加密、公钥解密——私钥加密
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher =Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,privateKey);
byte[] result = cipher.doFinal(qiji.getBytes());
System.out.println("传入字符串为" + qiji);
System.out.println("使用 Private Key 对字符串加密:");
System.out.println("加密结果:" + Base64.encodeBase64String(result));


// 私钥加密、公钥解密——解密
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,publicKey);
result = cipher.doFinal(result);
System.out.println("使用 Public Key 对上述加密结果进行解密");
System.out.println("解密结果: " + new String(result));
System.out.println();


// 公钥加密、私钥解密——加密
x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
byte[] result2 = cipher.doFinal(qiji.getBytes());
System.out.println("传入字符串为:" + qiji);
System.out.println("使用 Public Key 对字符串进行加密");
System.out.println("公钥加密结果:" + Base64.encodeBase64String(result2));


// 公钥加密、私钥解密——解密
pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,privateKey);
result2 = cipher.doFinal(result2);
System.out.println("使用 Private Key 进行解密:");
System.out.println("解密结果" + new String(result2));

} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
}

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
创建共钥成功!
Public Key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKkkz49eD/prF5uarqZUCmzEETLbCyM3S/GJ1mVPo7awwg4n19exVLizuKGpddIWqv15xcMENxIDqQBbe/cmU1ECAwEAAQ==
创建私钥成功!
Private Key: MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEAqSTPj14P+msXm5quplQKbMQRMtsLIzdL8YnWZU+jtrDCDifX17FUuLO4oal10haq/XnFwwQ3EgOpAFt79yZTUQIDAQABAkEAjrPb2d1GJcRMep+aUgH9eZ5B1GIxl1iD3hiopXj3ap16C2kUUoc2nsGXt3DOEgvXbP4mIeY01EAdsO1adkEjAQIhAPcRqEkNDLheVb153I+4yFEMdOfkYWSE6ITH+U+rVKs5AiEAr0ILXYyRDGhUgYfhBd2gUDuzynEuncIbALs7D9n6sNkCIQDRBtlPZID8gqMbeLwHxBeFqnpFrkxPlLp7jAv7QUKS0QIgG0gysLtjEQVksk1OsDUR8at5j3gTA6flwDVlOlB6f/ECIQDwuBNovCnxtiOPv14EJ2P11gmFSRfImfWTeY/9Idfe1g==
公钥的长度比较短!!!据说是为了方便保存

传入字符串为Hi,I'm ARNO
使用 Private Key 对字符串加密:
加密结果:OiX/8ENuc8m0WmKvvqXYVNeZhd2wZkY84btwfE6ubPo8jjWWL1BW+9cDERdeYhjWmlquUEcX+IqefUIFsppJfA==
使用 Public Key 对上述加密结果进行解密
解密结果: Hi,I'm ARNO

传入字符串为:Hi,I'm ARNO
使用 Public Key 对字符串进行加密
公钥加密结果:XkPhdtQH4ywyJeao7yan7XxZXnCLAe5WAlqY8xzSwRJsks/739VL1C9G/mg9zlmHi+F9etaxxy9HBUrjrfjkgg==
使用 Private Key 进行解密:
解密结果Hi,I'm ARNO

使用场景

非对称加密算法——算法

补充

密码常用术语 2

密码分析:接货密文者试图通过分析截获的密文从而推断出原来的明文或密钥的过程。
主动攻击:攻击者非法入侵密码系统,采用伪造、修改、删除等手段向系统注入假消息进行欺骗。(对密文具有破坏作用)
被动攻击:对一个保密系统采取截获密文并对其进行分析和攻击(对密文没有破坏作用)
密码体制:由明文空间、密文空间、密钥空间、加密算法和解密算法 5 部分构成。

密码常用术语 3

密码协议:也称安全协议,指以密码学为基础的消息交换的通信协议,目的是在网络环境中提供安全的服务。
密码系统:指用于加密、解密的系统
柯克霍夫原则:数据的安全基础密钥而不是算法的保密。及系统的安全取决于密钥,对密钥保密,对算法公开。——现代密码学设计的基本原则。

参考资料

  • JAVA 实现 Base64 加密 http://www.imooc.com/learn/285
  • JAVA实现对称加密 http://www.imooc.com/view/287
  • JAVA实现非对称加密 http://www.imooc.com/view/288
  • 扫盲 HTTPS 和 SSL/TLS 协议[1]:背景知识、协议的需求、设计的难点
  • Base64 - 维基百科 https://zh.wikipedia.org/wiki/Base64
  • 对称密钥加密 - 维基百科 https://zh.wikipedia.org/对称密钥加密
  • 非对称加密 - 维基百科 https://zh.wikipedia.org/非对称加密
12
Arno

Arno

Simplicity is prerequisite for reliability

18 日志
18 标签
© 2016 Arno
由 Hexo 强力驱动
主题 - NexT.Muse