Base64 编码的编程使用
密码学综述
密码学基本功能
1)机密性
2)鉴别
3)报文完整性
4)不可否认性
基本模型
密码学算法的分类
- 消息编码: Base64
- 消息摘要: MD类、SHA类、MAC
- 对称密码: DES、3DES、 AES
- 非对称密码: RSA、DH密钥交换
- 数字签名: RSASignature、DSASignature
密码学五元组
- 明文
- 密文
- 加密算法(公开)
- 解密算法(公开)
- 密钥
密钥
密钥和密码的巨大区别
密钥!=密码
Key != Password
密钥+规则==密码
在密码破解者看来,拿到密钥就等于有了密码!所以,重点在密钥
对称密码(传统密码)与非对称密码(公钥密码)
- 对称密码:加解密使用相同密钥的密码体制
- 非对称密码:加解密使用不同的密钥一公钥与私钥
Java编程中常用类
- 消息编码
BASE64Encoder、BASE64Decoder - 消息摘要
MessageDigest - 对称密码
KeyGenerator、SecretKey、 Cipher - 非对称密码
KeyPairGenerator、KeyFactory、 KeyPair、PublicKey、 PrivateKey、 Cipher - 数字签名
Signature
Base64 算法的编程使用
- Base64编码示例
密文: UGFyYXRlcmE=
明文: Paratera
- Base64算法定义
Base64是一种基于64个字符的编码算法,以任意8位字节序列组合的描述形式,这种形式不易直接识别。经Base64编码后的字符串的字符数是以4为单位的整数倍。 - Base64 密钥
4.Base64 编程使用
引入sun.misc.BASE64Decoder.jar
1、加密:
byte[] data = "Paratera".getBytes();
String result= new BASE64Encoder().encode(data) ;
2、解密:
byte[] result = new BASE64Decoder().decodeBuffer(data) ;
Base64 算法的实际应用
使用Telnet 发送邮件:
pubLic class Base64Util {
public static String enc ryptBase64(byte[] data){
return new BASE64Encoder().encode(data);
}
public static String dec ryptBase64(String data) throws IOException{
byte[] resultBytes = new BASE64Decoder().decodeBuffer(data);
return new String( resultBytes);
}
}
pubLic class SMTPMain {
public static void main(String[] args) {
//用户名密码
String sender = "cnsmtp01@163.com";
String receiver = "cnsmtp02@163. com";
String password = "computer";
//将用户名和密码进行Base64编码
String userBase64 = Base64Util.encryptBase64(sender.substring(0, sender.index0f("@")).getBytes());
String passBase64 = Base64Util.encryptBase64(password.getBytes());
try {
Socket socket = new Socket("smtp.163.com", 25);
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
PrintWriter writter = new PrintWriter(outputStream, true);
System.out.println(reader.readLine());
// HELO
writter.println("HELO Paratera");
System.out.println(reader.readLine());
// AUTH LOGIN >> >Base64
writter.println( "AUTH LOGIN");
System.out.println(reader.readLine());
writter.println(userBase64);
System.out.println(reader.readLine());
writter.println(passBase64);
System.out.println(reader.readLine());
// Set "MAIL FROM" and "RCPT TO"
writter.println("MAIL FROM:<" + sender + ">");
System.out.println(reader.readLine());
writter.println( "RCPT TO:<" + receiver + ">");
System.out.println(reader.readLine());
// Set "DATA"
writter.println("DATA");
System.out.println(reader.readLine());
writter.println("SUBJECT:你好并行集团");
writter.println("FROM:" + sender);
writter.println("T0:" + receiver);
writter.println("Content-Type: text/plain;charset=\"gb2312\"");
writter.println();
writter.println("北京并行科技股份有限公司(简称并行科技,PARATERA,股票代码:839493,挂牌新三板)成立于2007年,是国内领先的超算云服务和运营服务提供商,提供超算公有云服务、超算行业云服务、AI云服务、设计仿真云和计算资源建设及运营服务。");
writter.println(".");
writter.println("");
System.out.println(reader.readLine());
//发送完毕了, 和服务器拜拜
writter.println("RSET");
System.out.println(reader.readLine());
writter.println("QUIT");
System.out.println(reader.readLine());
} catch (Exception e) {
e.printStackTrace();
}
}
}
消息摘要的编程使用
消息摘要概述
唯一对应一个消息或文本的固定长度的值,由一个单向Hash加密函数对消息进行作用而产生
消息摘要的分类:
- (1) MD (Message Digest) :消息摘要算法
- (2) SHA (Secure Hash Algorithm) : 安全散列算法
- (3) MAC (Message Authentication Code) :消息认证码算法
消息摘要的日常应用
验证数据完整性(防止在传输途中被篡改)
MD算法的编程使用
为计算机安全领域广泛使用的一种散列函数,用以提供消息的
完整性
保护
MD系列算法(JDK)
算法 | 数据长度 | 摘要长度 |
---|---|---|
MD2 | 任意 | 128 |
MD5 | 任意 | 128 |
MD算法编程使用
核心代码
//初始化MessageDigest
MessageDigest md5 = MessageDigest.getInstance("MD5");
//更新, data为原始数据
md5.update(data);
/生成摘要
byte[] result= md5.digest();
完整示例代码:
// ---------1.BytesToHex.java---------
package net.wljy.crypt.util;
/**
* 字节转16进制
*
* @author paratera
*
*/
public class BytesToHex {
public static String fromBytesToHex(byte[] resultBytes) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < resultBytes.length; i++) {
if (Integer.toHexString(0xFF & resultBytes[i]).length() == 1) {
builder.append("0").append(Integer.toHexString(0xFF & resultBytes[i]));
} else {
builder.append(Integer.toHexString(0xFF & resultBytes[i]));
}
}
return builder.toString();
}
}
// ---------2.MessageDigestUtil.java---------
package net.wljy.crypt;
import java.io.File;
import java.io.FileInputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import net.wljy.crypt.util.BytesToHex;
public class MessageDigestUtil {
/**
* MD5字符串加密
* @param data 待加密字符串
* @return
*/
public static String encryptMD5(byte [] data) {
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
md5.update(data);
byte[] resultBytes = md5.digest();
return BytesToHex.fromBytesToHex(resultBytes);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 获取文件MD5值
* @param filePath 文件路径
* @return
*/
public static String getMD5ofFile(String filePath) {
FileInputStream fis;
try {
fis = new FileInputStream(new File(filePath));
DigestInputStream dis = new DigestInputStream(fis, MessageDigest.getInstance("MD5"));
byte[] buffer = new byte[1024];
int read = dis.read(buffer, 0, 1024);
while(read != -1) {
read = dis.read(buffer, 0, 1024);
}
MessageDigest md = dis.getMessageDigest();
return BytesToHex.fromBytesToHex(md.digest());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
// ---------3.MD5Test.java---------
package net.wljy.crypt;
public class MD5Test {
public static final String DATA = "并行集团";
public static void main(String[] args) {
String md5Str = MessageDigestUtil.encryptMD5(DATA.getBytes());
System.out.println(md5Str);
String fileMd5Str = MessageDigestUtil.getMD5ofFile("D:/API接口文档.html");
System.out.println("文件MD5:" + fileMd5Str);
}
}
SHA算法的编程使用
安全哈希算法,主要适用于数字签名标准里面定义的数字签名算法
SHA算法种类
算法 | 数据长度 | 摘要长度 |
---|---|---|
SHA-1 | 任意 | 160 |
SHA-256 | 任意 | 256 |
SHA-384 | 任意 | 384 |
SHA-512 | 任意 | 512 |
核心代码
//初始化MessageDigest
MessageDigest sha = MessageDigest.getInstance("SHA-x"); // SHA-x需替换为具体的算法名称
//更新, data为原始数据
sha.update(data);
/生成摘要
byte[] result= sha.digest();
示例代码:
/**
* 计算某一数据的hash摘要值
* @param data
* @return
*/
public static String encryptSHA(byte [] data) {
try {
MessageDigest sha = MessageDigest.getInstance("SHA-256");
sha.update(data);
return BytesToHex.fromBytesToHex(sha.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
HMAC算法的编程使用
引言:
单一MD或SHA算法缺点?
摘要值容易被篡改!
结合了MD5和SHA算法的优势,同时用 密钥 对摘要加密,是一种更为安全的消息摘要算法。
HMAC算法的种类
算法 | 数据长度 | 摘要长度 |
---|---|---|
HmacMD5 | 任意 | 128 |
HmacSHA1 | 任意 | 160 |
HmacSHA256 | 任意 | 256 |
HmacSHA384 | 任意 | 384 |
HmacSHA512 | 任意 | 512 |
如何生成密钥
KeyGenerator!
核心代码
1.构建密钥
//初始化KeyGenerator
KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
//产生密钥
SecretKey secretKey = keyGen.generateKey();
//得到密钥字节数组
byte[] key= secretKey.getEncoded();
2.执行消息摘要
//从字节数组还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacMD5");
//实例化Mac
Mac mac = Mac.getInstance("HmacMD5");
//用密钥初始化Mac
mac.init(secretKey);
//执行消息摘要
byte[] result = mac.doFinal(data);
散列函数特征:
- (1)输入任意长度数据,输出固定长度散列值,计算很容易,过程不可逆
- (2)对于某数据,其散列值固定
- (3)两个数据不同,则对应的散列值也不同
- (4)两个散列值不同,则对应的原始输入数据也不同
2.散列函数破解
(1)真破解:2005年2月,王小云教授破解了SHA-1 算法,已知数据A和其散列值,找到了另一个数据B与A的散列值相同
(2)假破解:根据数据库查询散列值,找到其对应的数据明文,根本在于数据库的查询!
对称密码的编程使用
对称密码概述
1、加密密钥和解密密钥相同,对于大多数对称密码算法,加解密过程互逆
2、加解密通信模型
3、特点:算法公开、计算量小、加密速度快、加密效率高
4、弱点:双方都使用同样密钥,安全性得不到保证
5、分组密码工作模式
- (1) ECB: 电子密码本
- (2) CBC: 密文链接
- (3) CFB: 密文反馈
- (4) OFB:输出反馈
- (5) CTR: 计数器
6、分组密码填充方式 - (1) NoPadding
- (2) PKCS5Padding
- (3) ISO10126Padding
7、常用对称密码:
- (1) DES (Data Encryption Standard)
- (2) 3DES (Triple DES、DESede)3重DES
- (3) AES (Advanced Encryption Standard)
DES算法的编程使用
- DES:数据加密标准,是对称加密算法领域中的典型算法
- 特点:密钥偏短(56位)、 生 命周期短
- JDK实现
| 算法 | 密钥长度 | 默认密钥长度 | 工作模式 | 填充方式 |
DES | 56 | 56 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8-CFB128、OFB、OFB8-OFB128 | NoPadding、PKCS5Padding、ISO10126Padding |
4、示例代码
// ---------1.DESUtil.java---------
package net.wljy.crypt.des;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class DESUtil {
/**
* 生成密钥
*
* @return
*/
public static byte[] initKey() {
try {
KeyGenerator keyGen = KeyGenerator.getInstance("DES");
keyGen.init(56);
SecretKey secretKey = keyGen.generateKey();
return secretKey.getEncoded();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* DES加密
*
* @param data 要加密的数据
* @param key 密钥
* @return
*/
public static byte[] encrypt(byte[] data, byte[] key) {
SecretKey secretKey = new SecretKeySpec(key, "DES");
try {
// DES/ECB/NoPadding --> 加密方式/工作模式/填充方式,没有严格要求的场景只写加密方式即可
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* DES加密
*
* @param data 要解密的数据
* @param key 密钥
* @return
*/
public static byte[] decrypt(byte[] encryptedData, byte[] key) {
SecretKey secretKey = new SecretKeySpec(key, "DES");
try {
// DES/ECB/NoPadding --> 加密方式/工作模式/填充方式,没有严格要求的场景只写加密方式即可
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(encryptedData);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
// ---------2.DESTest.java---------
package net.wljy.crypt.des;
import net.wljy.crypt.util.BytesToHex;
public class DESTest {
public static final String DATA = "并行集团";
public static void main(String[] args) {
// 获取密钥
byte[] initKey = DESUtil.initKey();
System.out.println("secretKey:" + BytesToHex.fromBytesToHex(initKey));
// 加密数据
byte[] desResultData = DESUtil.encrypt(DATA.getBytes(), initKey);
System.out.println("desResultData:" + BytesToHex.fromBytesToHex(desResultData));
// 解密数据
byte[] decryptResultData = DESUtil.decrypt(desResultData, initKey);
System.out.println("decryptResultData:" + new String(decryptResultData));
}
}
3DES算法的编程使用
1、3DES:将密钥长度增至112位或168位,通过增加迭代次数提高安全性
2、缺点:处理速度较慢、密钥计算时间较长、加密效率不高
3、JDK实现
算法 | 密钥长度 | 默认密钥长度 | 工作模式 | 填充方式 |
---|---|---|---|---|
3DES | 112、168 | 168 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8-CFB128、OFB、OFB8-OFB128 | NoPadding、PKCS5Padding、ISO10126Padding |
核心代码
1、生成密钥
KeyGenerator keyGen = KeyGenerator.getInstance("DESede");
keyGen.init(168); //可指定密钥长度为112或168, 默认为168
SecretKey secretKey = keyGen.generateKey();
2.加/解密
SecretKey secretKey = new SecretKeySpec(key, "DESede");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE,secretKey);
byte[] cipherByte = cipher.doFinal(data);
4、完整示例代码
// ---------1.TripleDESUtil.java---------
package net.wljy.crypt.tripledes;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* 3DES
*
* @author paratera
*
*/
public class TripleDESUtil {
/**
* 生成密钥
*
* @return
*/
public static byte[] initKey() {
KeyGenerator keyGen;
try {
keyGen = KeyGenerator.getInstance("DESede");
keyGen.init(168); // 112 168
SecretKey secretKey = keyGen.generateKey();
return secretKey.getEncoded();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* 3DES加密
*
* @param data 待加密数据
* @param key 密钥
* @return
*/
public static byte[] encrypt(byte[] data, byte[] key) {
try {
SecretKey secretKey = new SecretKeySpec(key, "DESede");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 3DES解密
*
* @param encrypedData 待解加密数据
* @param key 密钥
* @return
*/
public static byte[] decrypt(byte[] encrypedData, byte[] key) {
try {
SecretKey secretKey = new SecretKeySpec(key, "DESede");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(encrypedData);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
// ---------2.TripleDESTest.java---------
package net.wljy.crypt.tripledes;
import net.wljy.crypt.util.BytesToHex;
public class TripleDESTest {
public static final String DATA = "并行集团";
public static void main(String[] args) {
// 获取密钥
byte[] initKey = TripleDESUtil.initKey();
System.out.println("secretKey:" + BytesToHex.fromBytesToHex(initKey));
// 加密数据
byte[] resultData = TripleDESUtil.encrypt(DATA.getBytes(), initKey);
System.out.println("3DESResultData:" + BytesToHex.fromBytesToHex(resultData));
// 解密数据
byte[] decryptResultData = TripleDESUtil.decrypt(resultData, initKey);
System.out.println("3DESdecryptResultData:" + new String(decryptResultData));
}
}
AES算法的编程使用
1、AES:高级数据加密标准,能够有效抵御已知的针对DES算法的所有攻击
2、特点:密钥建立时间短、灵敏性好、内存需求低、安全性高
3、JDK实现
算法 | 密钥长度 | 默认密钥长度 | 工作模式 | 填充方式 |
---|---|---|---|---|
AES | 128、192、256 | 128 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8-CFB128、OFB、OFB8-OFB128 | NoPadding、PKCS5Padding、ISO10126Padding |
核心代码
1、生成密钥
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128); //默认128,获得无政策权限后可为192或256
SecretKey secretKey = keyGen.generateKey();
2、加/解密
SecretKey secretKey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,secretKey); // ENCRYPT_MODE:加密 || DECRYPT_MODE:解密
byte[] cipherByte = cipher.doFinal(data);
政策权限文件
keyGen.init(),如果给值为19或256会报错,JDK8及之前的文件可到如下地址下载政策文件:https://www.oracle.com/java/technologies/javase-jce-all-downloads.html。下载后覆盖jdk/jre/lib/security下的两个jar包即可。
非对称密码的编程使用
非对称密码概述
1、对称密码中的密钥配送存在不安全问题
2、非对称密码通信模型
3、非对称密码的特征
- (1).需要两个密钥来进行加密和解密,分别为公钥和私钥
- (2).公钥和私钥相互配对,称为KeyPair
4、非对称密码的优缺点
- (1).优点:相比于对称密码,安全性更高
- (2).缺点:加解密花费时间长、速度慢
5、常用非对称密码:
- (1).DH密钥交换算法
- (2).RSA算法
- (3).EIGamal算法
6、非对称密码的作用
- (1).密钥交换(DH)
- (2).加密/解密(RSA)
- (3).数字签名(RSA)
评论 (0)