密码学是网络安全、信息安全、区块链等产品的基础,常见的非对称加密、对称加密、散列函数等,都属于密码学范畴。
明文:加密前的消息叫
明文
(plain text)密文:加密后的文本叫
密文
(cipher text)密钥:只有掌握特殊
钥匙
的人,才能对加密的文本进行解密,这里的钥匙
就叫做密钥
(key)
常见的加密算法:
-
MD5
信息摘要算法 -
DES
是对称性加密算法 -
RSA
是一种非对称加密算法
一、消息摘要
摘要算法
就是我们常说的散列函数、哈希函数(Hash Function),它能够把任意长度的数据“压缩”成固定长度、而且独一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指纹”。
作用:保证信息的完整性
特点:
-
不可逆
:只有算法,没有秘钥,只能加密,不能解密 -
难题友好性
:想要破解,只能暴力枚举 -
发散性
:只要对原文进行一点点改动,摘要就会发生剧烈变化抗 -
碰撞性
:原文不同,计算后的摘要也要不同
常见消息摘要算法:
-
MD5
-
SHA1
-
SHA256
-
SHA512
二、对称性加密算法
对称加密
指的就是加密
和解密
使用同一个秘钥,所以叫做对称加密
。对称加密只有一个秘钥,作为私钥
。
对称加密算法:
-
DES
-
AES
-
3DES
特点:
-
加密速度快, 可以加密大文件
-
密文可逆, 一旦密钥文件泄漏, 就会导致数据暴露
-
加密后编码表找不到对应字符, 出现乱码
-
一般结合Base64使用
具体实现:
Java实现AES加解密_十点半的毛毛雨的博客-CSDN博客
三、非对称性加密算法
非对称加密
指的是:加密和解密使用不同的秘钥
,一把作为公开的公钥,另一把作为私钥。公钥加密的信息,只有私钥才能解密。私钥加密的信息,只有公钥才能解密
。
非对称加密算法:
-
RSA
-
ECC
特点:
-
加密和解密使用不同的密钥
-
如果使用私钥加密, 只能使用公钥解密
-
如果使用公钥加密, 只能使用私钥解密
-
处理数据的速度较慢, 因为安全级别高
3.1代码实现
实现思路:
1、先生成对应的公钥和似钥文件
2、读取公钥或者私钥匙文件获取口令
3、加密(如果使用私钥加密, 只能使用公钥解密,如果使用公钥加密, 只能使用私钥解密
)
4、解密
生成密钥文件:
/*** 生成秘钥* @param algorithm 算法* @param pubPath 公钥保存路径* @param priPath 私钥保存路径*/public static void generateKey(String algorithm,String pubPath,String priPath) throws NoSuchAlgorithmException, IOException {// 1. 获取密钥生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);// 2. 获取密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();// 3. 获取公钥PublicKey publicKey = keyPair.getPublic();// 4. 获取私钥PrivateKey privateKey = keyPair.getPrivate();// 5. 获取byte数组byte[] publicKeyEncoded = publicKey.getEncoded();byte[] privateKeyEncoded = privateKey.getEncoded();// 6. 编码BASE64编码String publicKeyString = Base64.encode(publicKeyEncoded);String privateKeyString = Base64.encode(privateKeyEncoded);// 7. 保存文件,保存在项目中的target目录下FileUtils.writeStringToFile(new File(pubPath),publicKeyString, Charset.forName("UTF-8"));FileUtils.writeStringToFile(new File(priPath),privateKeyString, Charset.forName("UTF-8"));}
读取公钥和私钥:
/*** 读取公钥文件* @param publicPath* @param algorithm* @return*/public static PublicKey getPublicKey(String publicPath,String algorithm) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {// 1. 读取文件String s = FileUtils.readFileToString(new File(publicPath), Charset.forName("UTF-8"));// 2. 获取密钥工厂KeyFactory keyFactory = KeyFactory.getInstance(algorithm);// 3. 构建秘钥规范X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(s));return keyFactory.generatePublic(x509EncodedKeySpec);}/*** 读取公钥文件* @param PrivatPath 私钥路径* @param algorithm 算法* @return*/public static PrivateKey getPrivatKey(String PrivatPath,String algorithm) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {// 1. 读取文件String s = FileUtils.readFileToString(new File(PrivatPath), Charset.forName("UTF-8"));// 2. 获取密钥工厂KeyFactory keyFactory = KeyFactory.getInstance(algorithm);// 3. 构建秘钥规范PKCS8EncodedKeySpec pes = new PKCS8EncodedKeySpec(Base64.decode(s));return keyFactory.generatePrivate(pes);}
3.1.1实现加密:
/*** 加密* @param input 原文* @param key 密钥* @param algorithm 算法* @return*/public static String encryptRSA(String input,Key key,String algorithm) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {// 1. 创建加密对象Cipher cipher = Cipher.getInstance(algorithm);// 2. 初始化加密cipher.init(Cipher.ENCRYPT_MODE,key);// 3. 公钥加密byte[] bytes = cipher.doFinal(input.getBytes());return Base64.encode(bytes);}
调用:
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchPaddingException {// 1. 原文String input = "我是曾阿牛";// 2. 加密算法String algorithm = "RSA";// 公钥加密 --> 私钥解密// 3. 获取公钥PublicKey publicKey = getPublicKey("a.pub", algorithm);// 4. 加密String s = encryptRSA(input, publicKey, algorithm);}
3.1.2解密
读取私钥文件并解密操作:
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchPaddingException {// 1. 加密算法String algorithm = "RSA";// 密文String s = "A密文";// 2、读取私钥PrivateKey privatKey = getPrivatKey("a.pri", algorithm);// 解密String s1 = decryptRSA(s, privatKey, algorithm);System.out.println(s1);}