发布于2021-03-10 18:17 阅读(815) 评论(0) 点赞(25) 收藏(0)
在对称加密算法中,数据发送方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。接受方收到密文后,若想解读原文,则需要使用加密用过的密文及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在对称加密算法中,使用的密钥只有一个,双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。
常见的对称加密算法:
特点:
加密模式:
填充模式:当需要按块处理的数据,数据长度不符合时,按照一定的方法填充满块的长度的规则
Demo代码:
package encryptAndDecrypt;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* @className: AesDesDemo
* @description: 使用DES加密解密,加密和解密都是使用同一个密钥
* @author: charon
* @create: 2021-02-25 08:27
*/
public class AesDesDemo {
public static void main(String[] args) throws Exception {
// 需要加密的内容,如果是不使用填充模式,那么密文的字节数必须是8的整数倍
String input = "charon周1234567";
// 密钥,DES加密的密钥必须是8位,如果是AES加密的密钥必须是16位
String key = "12345678";
// 加密算法,DES表示加密类型,CBC表示加密模式,NoPadding表示填充模式。
// 默认情况下是使用 DES/ECB/PKCS5padding
String algorithm = "DES/CBC/NoPadding";
String algorithmType = "DES";
//偏移量,是使用cbc的加密模式,在使用iv向量进行加密的时候,IV也必须是8位
String offset = "12345678";
// 加密
String encryptDes = encryptDES(input, key, algorithm, algorithmType,offset);
System.out.println("密文: " + encryptDes);
// 解密
String decryptDES = decryptDES(encryptDes, key, algorithm, algorithmType,offset);
System.out.println("解密: "+ decryptDES);
}
/**
* 解密
* @param encryptDes 密文
* @param key 密钥
* @param algorithm 解密算法
* @param algorithmType 解密类型
* @param offset 偏移量
* @return
*/
private static String decryptDES(String encryptDes, String key, String algorithm, String algorithmType,String offset) throws Exception {
// 获取解密对象
Cipher cipher = Cipher.getInstance(algorithm);
// 创建加密规则
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(),algorithmType);
// 创建iv向量
IvParameterSpec ivParameterSpec = new IvParameterSpec(offset.getBytes());
// 初始化解密规则
cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,ivParameterSpec);
// 加密
byte[] bytes = cipher.doFinal(Base64.decode(encryptDes));
return new String(bytes);
}
/**
* 加密
* @param input 加密内容
* @param key 密钥
* @param algorithm 加密算法
* @param algorithmType 加密类型
* @param offset 偏移量
* @return 密文
*/
private static String encryptDES(String input, String key, String algorithm, String algorithmType,String offset) throws Exception {
// 获取加密对象
Cipher cipher = Cipher.getInstance(algorithm);
// 创建加密规则
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(),algorithmType);
// 创建iv变量,iv向量,是使用cbc的加密模式
// 在使用iv向量进行加密的时候,IV也必须是8位
IvParameterSpec ivParameterSpec = new IvParameterSpec(offset.getBytes());
// 初始化加密
cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,ivParameterSpec);
// 加密
byte[] bytes = cipher.doFinal(input.getBytes());
// 返回加密后的数据
return Base64.encode(bytes);
}
}
与对称加密算法不同,非对称加密算法需要两个密钥:公钥和私钥。公钥与私钥是一对,如果使用公钥对数据进行加密,那么只能有对应的私钥才能解密;如果使用私钥进行加密,那么只能用对应的公钥才能解密。因为加密和解密是使用的两个不同的密钥。
常见的非对称加密算法:
特点:
demo代码:
package encryptAndDecrypt;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.commons.io.FileUtils;
import javax.crypto.Cipher;
import java.io.File;
import java.nio.charset.Charset;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* @className: RsaDemo
* @description: 非对称加密之RSA
* @author: charon
* @create: 2021-02-25 11:05
*/
public class RsaDemo {
public static void main(String[] args) throws Exception {
String algorithm = "RSA";
// 生成密钥对并保存在本地文件中,这样就可以不用每次都重新申请了。
// 也有系统为了更安全,每次都会新生成密钥,然后将公钥返回给客户端,私钥存入redis中,解密的时候从根据session从redis中取对应的私钥
generateKeyToFile(algorithm, "pub.txt", "pri.txt");
// 获取公钥
PublicKey publicKey = getPublicKey("pub.txt", "RSA");
// 获取私钥
PrivateKey privateKey = getPrivateKey("pri.txt", "RSA");
// 原文
String input = "charon周";
// 加密
String encryptRSA = encryptRSA(input,algorithm,publicKey);
System.out.println("密文:"+ encryptRSA);
// 解密
String decryptRSA = decryptRSA(encryptRSA,algorithm,privateKey);
System.out.println("原文:"+ decryptRSA);
}
/**
* 解密
* @param encryptRSA 密文
* @param algorithm 算法
* @param privateKey 私钥
* @return 原文
*/
private static String decryptRSA(String encryptRSA, String algorithm, PrivateKey privateKey) throws Exception{
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE,privateKey);
byte[] bytes = cipher.doFinal(Base64.decode(encryptRSA));
return new String(bytes);
}
/**
* 加密
* @param input 原文
* @param algorithm 加密算法
* @param publicKey 公钥
* @return 密文
*/
private static String encryptRSA(String input, String algorithm, PublicKey publicKey) throws Exception{
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
byte[] bytes = cipher.doFinal(input.getBytes());
return Base64.encode(bytes);
}
/**
* 获取私钥
* @param privateKeyPath 私钥文件路径
* @param algorithm 算法
* @return 私钥
*/
public static PrivateKey getPrivateKey(String privateKeyPath, String algorithm) throws Exception {
// 读取文件内容
String strPrivateKey = FileUtils.readFileToString(new File(privateKeyPath), Charset.defaultCharset());
// 创建key工厂
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 创建私钥规则
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(strPrivateKey));
return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
}
/**
* 获取公钥
* @param publicKeyPath 公钥文件路径
* @param algorithm 算法
* @return 公钥
*/
public static PublicKey getPublicKey(String publicKeyPath, String algorithm) throws Exception{
// 读取文件内容
String strPublicKey = FileUtils.readFileToString(new File(publicKeyPath), Charset.defaultCharset());
// 创建key工厂
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 创建公钥规则
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(strPublicKey));
return keyFactory.generatePublic(x509EncodedKeySpec);
}
/**
* 生成密钥对,并放入本地文件
* @param algorithm
* @param publicKeyPath
* @param privateKeyPath
*/
private static void generateKeyToFile(String algorithm, String publicKeyPath, String privateKeyPath) throws Exception{
// 生成实例
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 生成私钥
PrivateKey privateKey = keyPair.getPrivate();
// 获取私钥字节数组
byte[] privateKeyEncoded = privateKey.getEncoded();
// 生成公钥
PublicKey publicKey = keyPair.getPublic();
// 获取公钥的字节数组
byte[] publicKeyEncoded = publicKey.getEncoded();
// base64编码
String strPrivateKeyEncoded = Base64.encode(privateKeyEncoded);
String strPublicKeyEncoded = Base64.encode(publicKeyEncoded);
// 存到文件中
FileUtils.write(new File(privateKeyPath),strPrivateKeyEncoded, Charset.forName("UTF-8"));
FileUtils.write(new File(publicKeyPath),strPublicKeyEncoded, Charset.forName("UTF-8"));
}
}
数字签名(又称公钥数字签名)是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。它是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术来实现的,用于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。数字签名是非对称密钥加密技术与数字摘要技术的应用。
demo代码:
package encryptAndDecrypt;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
/**
* @className: SignatureDemo
* @description: 数字签名
* @author: charon
* @create: 2021-02-25 15:40
*/
public class SignatureDemo {
public static void main(String[] args) throws Exception{
// 这里直接使用之前的公钥和私钥
// 获取公钥
PublicKey publicKey = RsaDemo.getPublicKey("pub.txt", "RSA");
// 获取私钥
PrivateKey privateKey = RsaDemo.getPrivateKey("pri.txt", "RSA");
String input = "charon周";
// 获取签名
String signature = getSignature(input, "Sha256withrsa", privateKey);
System.out.println("签名:" + signature);
// 校验签名
boolean verifySignature = verifySignature(input, "Sha256withrsa", publicKey, signature);
System.out.println("结果: "+ verifySignature);
}
/**
* 校验签名
* @param input 原文
* @param algorithm 算法
* @param publicKey 公钥
* @param signatureData 签名
* @return
*/
private static boolean verifySignature(String input, String algorithm, PublicKey publicKey, String signatureData) throws Exception{
Signature signature = Signature.getInstance(algorithm);
signature.initVerify(publicKey);
signature.update(input.getBytes());
// 校验数据
boolean verify = signature.verify(Base64.decode(signatureData));
return verify;
}
/**
* 签名
* @param input 原文
* @param algorithm 算法
* @param privateKey 私钥
* @return 签名
*/
private static String getSignature(String input, String algorithm, PrivateKey privateKey) throws Exception{
// 获取签名对象
Signature signature = Signature.getInstance(algorithm);
// 初始化签名
signature.initSign(privateKey);
signature.update(input.getBytes());
// 签名
byte[] bytes = signature.sign();
return Base64.encode(bytes);
}
}
参考文章:
https://blog.csdn.net/u014294681/article/details/86705999
原文链接:https://www.cnblogs.com/pluto-charon/p/14450440.html
作者:小可爱们
链接:http://www.javaheidong.com/blog/article/112334/3f32208669cbd82857b6/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!