diff --git a/数据结构与算法/source code/securityAlgorithm/.classpath b/数据结构与算法/source code/securityAlgorithm/.classpath
new file mode 100644
index 00000000..0a1daddd
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/.classpath
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/数据结构与算法/source code/securityAlgorithm/.gitignore b/数据结构与算法/source code/securityAlgorithm/.gitignore
new file mode 100644
index 00000000..b83d2226
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/数据结构与算法/source code/securityAlgorithm/.project b/数据结构与算法/source code/securityAlgorithm/.project
new file mode 100644
index 00000000..7b9c539d
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/.project
@@ -0,0 +1,23 @@
+
+
+ securityAlgorithm
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/数据结构与算法/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs b/数据结构与算法/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000..f9fe3459
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/test/java=UTF-8
+encoding/=UTF-8
diff --git a/数据结构与算法/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs b/数据结构与算法/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..abec6ca3
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/数据结构与算法/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs b/数据结构与算法/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 00000000..f897a7f1
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/数据结构与算法/source code/securityAlgorithm/pom.xml b/数据结构与算法/source code/securityAlgorithm/pom.xml
new file mode 100644
index 00000000..348847f6
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/pom.xml
@@ -0,0 +1,37 @@
+
+ 4.0.0
+
+ com.snailclimb.ks
+ securityAlgorithm
+ 0.0.1-SNAPSHOT
+ jar
+
+ securityAlgorithm
+ http://maven.apache.org
+
+
+ UTF-8
+
+
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+
+ commons-codec
+ commons-codec
+ 1.8
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.56
+
+
+
+
diff --git a/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java
new file mode 100644
index 00000000..1c6fd6df
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/Base64Demo.java
@@ -0,0 +1,49 @@
+package com.snailclimb.ks.securityAlgorithm;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Base64;
+
+public class Base64Demo {
+
+ public static void main(String[] args) throws UnsupportedEncodingException {
+ // TODO Auto-generated method stub
+ CommonsCodecDemo();
+ bouncyCastleDemo();
+ jdkDemo();
+ }
+
+ static String str = "你若安好,便是晴天";
+
+ /**
+ * commons codec实现Base64加密解密
+ */
+ public static void CommonsCodecDemo() {
+ // 加密:
+ byte[] encodeBytes = org.apache.commons.codec.binary.Base64.encodeBase64(str.getBytes());
+ System.out.println("commons codec实现base64加密: " + new String(encodeBytes));
+ // 解密:
+ byte[] decodeBytes = org.apache.commons.codec.binary.Base64.decodeBase64(encodeBytes);
+ System.out.println("commons codec实现base64解密: " + new String(decodeBytes));
+ }
+
+ /**
+ * bouncy castle实现Base64加密解密
+ */
+ public static void bouncyCastleDemo() {
+ // 加密
+ byte[] encodeBytes = org.bouncycastle.util.encoders.Base64.encode(str.getBytes());
+ System.out.println("bouncy castle实现base64加密: " + new String(encodeBytes));
+ // 解密
+ byte[] decodeBytes = org.bouncycastle.util.encoders.Base64.decode(encodeBytes);
+ System.out.println("bouncy castle实现base64解密:" + new String(decodeBytes));
+ }
+
+ public static void jdkDemo() throws UnsupportedEncodingException {
+ // 加密
+ String encodeBytes = Base64.getEncoder().encodeToString(str.getBytes("UTF-8"));
+ System.out.println("JDK实现的base64加密: " + encodeBytes);
+ //解密
+ byte[] decodeBytes = Base64.getDecoder().decode(encodeBytes.getBytes("UTF-8"));
+ System.out.println("JDK实现的base64解密: "+new String(decodeBytes));
+ }
+}
diff --git a/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java
new file mode 100644
index 00000000..3339ea1c
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/DesDemo.java
@@ -0,0 +1,100 @@
+package com.snailclimb.ks.securityAlgorithm;
+
+import java.io.UnsupportedEncodingException;
+import java.security.SecureRandom;
+import javax.crypto.spec.DESKeySpec;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.SecretKey;
+import javax.crypto.Cipher;
+
+/**
+ * DES加密介绍 DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究,
+ * 后来被美国政府正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位密钥,以现代计算能力,
+ * 24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法,本文简单讲解DES的JAVA实现 。
+ * 注意:DES加密和解密过程中,密钥长度都必须是8的倍数
+ */
+public class DesDemo {
+ public DesDemo() {
+ }
+
+ // 测试
+ public static void main(String args[]) {
+ // 待加密内容
+ String str = "cryptology";
+ // 密码,长度要是8的倍数
+ String password = "95880288";
+
+ byte[] result;
+ try {
+ result = DesDemo.encrypt(str.getBytes(), password);
+ System.out.println("加密后:" + new String(result));
+ byte[] decryResult = DesDemo.decrypt(result, password);
+ System.out.println("解密后:" + new String(decryResult));
+ } catch (UnsupportedEncodingException e2) {
+ // TODO Auto-generated catch block
+ e2.printStackTrace();
+ } catch (Exception e1) {
+ e1.printStackTrace();
+ }
+ }
+
+ // 直接将如上内容解密
+
+ /**
+ * 加密
+ *
+ * @param datasource
+ * byte[]
+ * @param password
+ * String
+ * @return byte[]
+ */
+ public static byte[] encrypt(byte[] datasource, String password) {
+ try {
+ SecureRandom random = new SecureRandom();
+ DESKeySpec desKey = new DESKeySpec(password.getBytes());
+ // 创建一个密匙工厂,然后用它把DESKeySpec转换成
+ SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+ SecretKey securekey = keyFactory.generateSecret(desKey);
+ // Cipher对象实际完成加密操作
+ Cipher cipher = Cipher.getInstance("DES");
+ // 用密匙初始化Cipher对象,ENCRYPT_MODE用于将 Cipher 初始化为加密模式的常量
+ cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
+ // 现在,获取数据并加密
+ // 正式执行加密操作
+ return cipher.doFinal(datasource); // 按单部分操作加密或解密数据,或者结束一个多部分操作
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 解密
+ *
+ * @param src
+ * byte[]
+ * @param password
+ * String
+ * @return byte[]
+ * @throws Exception
+ */
+ public static byte[] decrypt(byte[] src, String password) throws Exception {
+ // DES算法要求有一个可信任的随机数源
+ SecureRandom random = new SecureRandom();
+ // 创建一个DESKeySpec对象
+ DESKeySpec desKey = new DESKeySpec(password.getBytes());
+ // 创建一个密匙工厂
+ SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 返回实现指定转换的
+ // Cipher
+ // 对象
+ // 将DESKeySpec对象转换成SecretKey对象
+ SecretKey securekey = keyFactory.generateSecret(desKey);
+ // Cipher对象实际完成解密操作
+ Cipher cipher = Cipher.getInstance("DES");
+ // 用密匙初始化Cipher对象
+ cipher.init(Cipher.DECRYPT_MODE, securekey, random);
+ // 真正开始解密操作
+ return cipher.doFinal(src);
+ }
+}
\ No newline at end of file
diff --git a/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java
new file mode 100644
index 00000000..5ce251df
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/IDEADemo.java
@@ -0,0 +1,46 @@
+package com.snailclimb.ks.securityAlgorithm;
+
+import java.security.Key;
+import java.security.Security;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Base64;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+public class IDEADemo {
+ public static void main(String args[]) {
+ bcIDEA();
+ }
+ public static void bcIDEA() {
+ String src = "www.xttblog.com security idea";
+ try {
+ Security.addProvider(new BouncyCastleProvider());
+
+ //生成key
+ KeyGenerator keyGenerator = KeyGenerator.getInstance("IDEA");
+ keyGenerator.init(128);
+ SecretKey secretKey = keyGenerator.generateKey();
+ byte[] keyBytes = secretKey.getEncoded();
+
+ //转换密钥
+ Key key = new SecretKeySpec(keyBytes, "IDEA");
+
+ //加密
+ Cipher cipher = Cipher.getInstance("IDEA/ECB/ISO10126Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+ byte[] result = cipher.doFinal(src.getBytes());
+ System.out.println("bc idea encrypt : " + Base64.encodeBase64String(result));
+
+ //解密
+ cipher.init(Cipher.DECRYPT_MODE, key);
+ result = cipher.doFinal(result);
+ System.out.println("bc idea decrypt : " + new String(result));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java
new file mode 100644
index 00000000..2b8e31f8
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5.java
@@ -0,0 +1,160 @@
+package com.snailclimb.ks.securityAlgorithm;
+
+public class MD5{
+ /*
+ *四个链接变量
+ */
+ private final int A=0x67452301;
+ private final int B=0xefcdab89;
+ private final int C=0x98badcfe;
+ private final int D=0x10325476;
+ /*
+ *ABCD的临时变量
+ */
+ private int Atemp,Btemp,Ctemp,Dtemp;
+
+ /*
+ *常量ti
+ *公式:floor(abs(sin(i+1))×(2pow32)
+ */
+ private final int K[]={
+ 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
+ 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,
+ 0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,
+ 0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,
+ 0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
+ 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,
+ 0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,
+ 0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,
+ 0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
+ 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,
+ 0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,
+ 0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,
+ 0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391};
+ /*
+ *向左位移数,计算方法未知
+ */
+ private final int s[]={7,12,17,22,7,12,17,22,7,12,17,22,7,
+ 12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
+ 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,
+ 15,21,6,10,15,21,6,10,15,21,6,10,15,21};
+
+
+ /*
+ *初始化函数
+ */
+ private void init(){
+ Atemp=A;
+ Btemp=B;
+ Ctemp=C;
+ Dtemp=D;
+ }
+ /*
+ *移动一定位数
+ */
+ private int shift(int a,int s){
+ return(a<>>(32-s));//右移的时候,高位一定要补零,而不是补充符号位
+ }
+ /*
+ *主循环
+ */
+ private void MainLoop(int M[]){
+ int F,g;
+ int a=Atemp;
+ int b=Btemp;
+ int c=Ctemp;
+ int d=Dtemp;
+ for(int i = 0; i < 64; i ++){
+ if(i<16){
+ F=(b&c)|((~b)&d);
+ g=i;
+ }else if(i<32){
+ F=(d&b)|((~d)&c);
+ g=(5*i+1)%16;
+ }else if(i<48){
+ F=b^c^d;
+ g=(3*i+5)%16;
+ }else{
+ F=c^(b|(~d));
+ g=(7*i)%16;
+ }
+ int tmp=d;
+ d=c;
+ c=b;
+ b=b+shift(a+F+K[i]+M[g],s[i]);
+ a=tmp;
+ }
+ Atemp=a+Atemp;
+ Btemp=b+Btemp;
+ Ctemp=c+Ctemp;
+ Dtemp=d+Dtemp;
+
+ }
+ /*
+ *填充函数
+ *处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)
+ *填充方式为先加一个0,其它位补零
+ *最后加上64位的原来长度
+ */
+ private int[] add(String str){
+ int num=((str.length()+8)/64)+1;//以512位,64个字节为一组
+ int strByte[]=new int[num*16];//64/4=16,所以有16个整数
+ for(int i=0;i>2]|=str.charAt(i)<<((i%4)*8);//一个整数存储四个字节,小端序
+ }
+ strByte[i>>2]|=0x80<<((i%4)*8);//尾部添加1
+ /*
+ *添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位
+ */
+ strByte[num*16-2]=str.length()*8;
+ return strByte;
+ }
+ /*
+ *调用函数
+ */
+ public String getMD5(String source){
+ init();
+ int strByte[]=add(source);
+ for(int i=0;i>i*8)%(1<<8))&0xff)).replace(' ', '0');
+
+ }
+ return str;
+ }
+ /*
+ *单例
+ */
+ private static MD5 instance;
+ public static MD5 getInstance(){
+ if(instance==null){
+ instance=new MD5();
+ }
+ return instance;
+ }
+
+ private MD5(){};
+
+ public static void main(String[] args){
+ String str=MD5.getInstance().getMD5("你若安好,便是晴天");
+ System.out.println(str);
+ }
+}
\ No newline at end of file
diff --git a/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java
new file mode 100644
index 00000000..3a8635d1
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/MD5Demo.java
@@ -0,0 +1,50 @@
+package com.snailclimb.ks.securityAlgorithm;
+
+import java.security.MessageDigest;
+
+public class MD5Demo {
+
+ // test
+ public static void main(String[] args) {
+ System.out.println(getMD5Code("你若安好,便是晴天"));
+ }
+
+ private MD5Demo() {
+ }
+
+ // md5加密
+ public static String getMD5Code(String message) {
+ String md5Str = "";
+ try {
+ //创建MD5算法消息摘要
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ //生成的哈希值的字节数组
+ byte[] md5Bytes = md.digest(message.getBytes());
+ md5Str = bytes2Hex(md5Bytes);
+ }catch(Exception e) {
+ e.printStackTrace();
+ }
+ return md5Str;
+ }
+
+ // 2进制转16进制
+ public static String bytes2Hex(byte[] bytes) {
+ StringBuffer result = new StringBuffer();
+ int temp;
+ try {
+ for (int i = 0; i < bytes.length; i++) {
+ temp = bytes[i];
+ if(temp < 0) {
+ temp += 256;
+ }
+ if (temp < 16) {
+ result.append("0");
+ }
+ result.append(Integer.toHexString(temp));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return result.toString();
+ }
+}
diff --git a/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java
new file mode 100644
index 00000000..c7ddf105
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/RSADemo.java
@@ -0,0 +1,249 @@
+package com.snailclimb.ks.securityAlgorithm;
+
+import org.apache.commons.codec.binary.Base64;
+
+import java.security.*;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+
+/**
+ * Created by humf.需要依赖 commons-codec 包
+ */
+public class RSADemo {
+
+ public static void main(String[] args) throws Exception {
+ Map keyMap = initKey();
+ String publicKey = getPublicKey(keyMap);
+ String privateKey = getPrivateKey(keyMap);
+
+ System.out.println(keyMap);
+ System.out.println("-----------------------------------");
+ System.out.println(publicKey);
+ System.out.println("-----------------------------------");
+ System.out.println(privateKey);
+ System.out.println("-----------------------------------");
+ byte[] encryptByPrivateKey = encryptByPrivateKey("123456".getBytes(), privateKey);
+ byte[] encryptByPublicKey = encryptByPublicKey("123456", publicKey);
+ System.out.println(new String(encryptByPrivateKey));
+ System.out.println("-----------------------------------");
+ System.out.println(new String(encryptByPublicKey));
+ System.out.println("-----------------------------------");
+ String sign = sign(encryptByPrivateKey, privateKey);
+ System.out.println(sign);
+ System.out.println("-----------------------------------");
+ boolean verify = verify(encryptByPrivateKey, publicKey, sign);
+ System.out.println(verify);
+ System.out.println("-----------------------------------");
+ byte[] decryptByPublicKey = decryptByPublicKey(encryptByPrivateKey, publicKey);
+ byte[] decryptByPrivateKey = decryptByPrivateKey(encryptByPublicKey, privateKey);
+ System.out.println(new String(decryptByPublicKey));
+ System.out.println("-----------------------------------");
+ System.out.println(new String(decryptByPrivateKey));
+
+ }
+
+ public static final String KEY_ALGORITHM = "RSA";
+ public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
+
+ private static final String PUBLIC_KEY = "RSAPublicKey";
+ private static final String PRIVATE_KEY = "RSAPrivateKey";
+
+ public static byte[] decryptBASE64(String key) {
+ return Base64.decodeBase64(key);
+ }
+
+ public static String encryptBASE64(byte[] bytes) {
+ return Base64.encodeBase64String(bytes);
+ }
+
+ /**
+ * 用私钥对信息生成数字签名
+ *
+ * @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(KEY_ALGORITHM);
+ // 取私钥匙对象
+ PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
+ // 用私钥对信息生成数字签名
+ Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
+ 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);
+ // KEY_ALGORITHM 指定的加密算法
+ 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));
+ }
+
+ public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
+ // 对密钥解密
+ byte[] keyBytes = decryptBASE64(key);
+ // 取得私钥
+ PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+ KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+ Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
+ // 对数据解密
+ Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+ cipher.init(Cipher.DECRYPT_MODE, privateKey);
+ return cipher.doFinal(data);
+ }
+
+ /**
+ * 解密
+ * 用私钥解密
+ *
+ * @param data
+ * @param key
+ * @return
+ * @throws Exception
+ */
+ public static byte[] decryptByPrivateKey(String data, String key) throws Exception {
+ return decryptByPrivateKey(decryptBASE64(data), key);
+ }
+
+ /**
+ * 解密
+ * 用公钥解密
+ *
+ * @param data
+ * @param key
+ * @return
+ * @throws Exception
+ */
+ public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
+ // 对密钥解密
+ byte[] keyBytes = decryptBASE64(key);
+ // 取得公钥
+ X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+ KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+ Key publicKey = keyFactory.generatePublic(x509KeySpec);
+ // 对数据解密
+ Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+ cipher.init(Cipher.DECRYPT_MODE, publicKey);
+ return cipher.doFinal(data);
+ }
+
+ /**
+ * 加密
+ * 用公钥加密
+ *
+ * @param data
+ * @param key
+ * @return
+ * @throws Exception
+ */
+ public static byte[] encryptByPublicKey(String data, String key) throws Exception {
+ // 对公钥解密
+ byte[] keyBytes = decryptBASE64(key);
+ // 取得公钥
+ X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+ KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+ Key publicKey = keyFactory.generatePublic(x509KeySpec);
+ // 对数据加密
+ Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+ return cipher.doFinal(data.getBytes());
+ }
+
+ /**
+ * 加密
+ * 用私钥加密
+ *
+ * @param data
+ * @param key
+ * @return
+ * @throws Exception
+ */
+ public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
+ // 对密钥解密
+ byte[] keyBytes = decryptBASE64(key);
+ // 取得私钥
+ PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+ KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+ Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
+ // 对数据加密
+ Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+ cipher.init(Cipher.ENCRYPT_MODE, privateKey);
+ return cipher.doFinal(data);
+ }
+
+ /**
+ * 取得私钥
+ *
+ * @param keyMap
+ * @return
+ * @throws Exception
+ */
+ public static String getPrivateKey(Map keyMap) throws Exception {
+ Key key = (Key) keyMap.get(PRIVATE_KEY);
+ return encryptBASE64(key.getEncoded());
+ }
+
+ /**
+ * 取得公钥
+ *
+ * @param keyMap
+ * @return
+ * @throws Exception
+ */
+ public static String getPublicKey(Map keyMap) throws Exception {
+ Key key = keyMap.get(PUBLIC_KEY);
+ return encryptBASE64(key.getEncoded());
+ }
+
+ /**
+ * 初始化密钥
+ *
+ * @return
+ * @throws Exception
+ */
+ public static Map initKey() throws Exception {
+ KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
+ keyPairGen.initialize(1024);
+ KeyPair keyPair = keyPairGen.generateKeyPair();
+ Map keyMap = new HashMap(2);
+ keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥
+ keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥
+ return keyMap;
+ }
+
+}
\ No newline at end of file
diff --git a/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java
new file mode 100644
index 00000000..ab19e3d0
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/SHA1Demo.java
@@ -0,0 +1,45 @@
+package com.snailclimb.ks.securityAlgorithm;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class SHA1Demo {
+
+ public static void main(String[] args) {
+ // TODO Auto-generated method stub
+ System.out.println(getSha1("你若安好,便是晴天"));
+
+ }
+
+ public static String getSha1(String str) {
+ if (null == str || 0 == str.length()) {
+ return null;
+ }
+ char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+ try {
+ //创建SHA1算法消息摘要对象
+ MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
+ //使用指定的字节数组更新摘要。
+ mdTemp.update(str.getBytes("UTF-8"));
+ //生成的哈希值的字节数组
+ byte[] md = mdTemp.digest();
+ //SHA1算法生成信息摘要关键过程
+ int j = md.length;
+ char[] buf = new char[j * 2];
+ int k = 0;
+ for (int i = 0; i < j; i++) {
+ byte byte0 = md[i];
+ buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
+ buf[k++] = hexDigits[byte0 & 0xf];
+ }
+ return new String(buf);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return "0";
+
+ }
+}
diff --git a/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme
new file mode 100644
index 00000000..5c2d452d
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/src/main/java/com/snailclimb/ks/securityAlgorithm/readme
@@ -0,0 +1,3 @@
+Des算法参考:http://blog.csdn.net/super_cui/article/details/70820983
+IDEA算法参考:https://www.xttblog.com/?p=1121
+RSA算法实现参考:https://www.cnblogs.com/xlhan/p/7120488.html
\ No newline at end of file
diff --git a/数据结构与算法/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java b/数据结构与算法/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java
new file mode 100644
index 00000000..93225451
--- /dev/null
+++ b/数据结构与算法/source code/securityAlgorithm/src/test/java/com/snailclimb/ks/securityAlgorithm/AppTest.java
@@ -0,0 +1,38 @@
+package com.snailclimb.ks.securityAlgorithm;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}