对称加密
加密和解密时使用相同的密钥,这种加密方法称为对称加密
分类
流加密:按顺序一个一个加密,如文本:123456,则先加密1再加密2,以此类推
块加密:分块分组加密,如文本:123456,若分3组,则先加密12,再加密34,以此类推
常见加密算法
DES
AES
特点
加密速度快, 可以加密大文件
密文可逆, 一旦密钥文件泄漏, 就会导致数据暴露
加密后再ASCII编码表找不到对应字符, 出现乱码
一般结合Base64使用,防止乱码
DES的使用 ======
DES是数据加密标准,是一种使用密钥加密的块算法。
Java的Cipher
类供加密和解密功能,在线文档:https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html
public static void main(String[] args) throws Exception {// 原文String input = "Hello Word";// 使用des进行加密,密钥必须是8个字节String key = "12345678";// 获取Cipher对象的算法String transformation = "DES";// 指定获取密钥的算法String algorithm = "DES";String encrypt = encrypt(input, key, transformation, algorithm);System.out.println("加密:" + encrypt);String decrypt = dncrypt(encrypt, key, transformation, algorithm);System.out.println("解密:" + decrypt);}/** * 加密数据 */private static String encrypt(String input, String key, String transformation, String algorithm) throws Exception {// 获取加密对象Cipher cipher = Cipher.getInstance(transformation);// 指定秘钥规则:传入密钥的字节数组与指定的算法SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);// 初始化加密对象: 指定加密模式与秘钥规则cipher.init(Cipher.ENCRYPT_MODE, sks);// 开始加密byte[] bytes = cipher.doFinal(input.getBytes());// 打印密文,由于bytes字节数字中存在负数,即ascii码有负数,解析不出来,将输出乱码System.out.println("bytes = " + new String(bytes));// 对字节数字进行Base64编码return Base64.encode(bytes);}/** * 解密数据 */private static String dncrypt(String input, String key, String transformation, String algorithm) throws Exception {// 获取Cipher对象Cipher cipher = Cipher.getInstance(transformation);// 指定秘钥规则:传入密钥的字节数组与指定的算法SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);// 初始化解密对象: 指定解密模式与秘钥规则cipher.init(Cipher.DECRYPT_MODE, sks);// 解密byte[] bytes = cipher.doFinal(Base64.decode(input));return new String(bytes);}
bytes = �Rd��ʩ� h��
加密:01Jk6AecyqnqsABousAVIA==
解密:Hello Word
AES的使用
AES是高级加密标准,用来替代DES。
public static void main(String[] args) throws Exception {// 原文String input = "Hello Word";// AES加密算法:密匙必须是16个字节String key = "1234567891234567";// 获取Cipher对象的算法String transformation = "AES";// 指定获取密钥的算法String algorithm = "AES";String encrypt = encrypt(input, key, transformation, algorithm);System.out.println("加密:" + encrypt);String decrypt = dncrypt(encrypt, key, transformation, algorithm);System.out.println("解密:" + decrypt);}
bytes = ��F�p��Ny�|08�k2
加密:/fZGj3CTnE5503wwONlrMg==
解密:Hello Word
Base64算法
Base64算法不是加密算法,是用于传输8Bit字节码的可读性编码算法之一。
可读性编码不改变信息内容,只改变信息内容的表现形式
Base64是说在编码过程中使用了64种字符:大写A到Z、小写a到z、数字0到9、“+”和“/”
构成
26个小写字母: a - z
26个大写字母: A - Z
10 个数字: 0 - 9
2个符号: + /
算法原理
base64是3个字节为一组,一个字节 8位,一共就是24位 ,然后把3个字节转成4组,每组6位(
3 * 8 = 4 * 6 = 24
)。
当每组6位时则缺少2位,在高位进行补0 ,于是控制了base64的取值范围在0-63位,所以就叫base64(
00111 111 = 32 + 16 + 8 + 4 + 2 + 1 =63
)
注意:
由于base64是三个字节一组 ,当一组三个字节位数不够的时候,会使用等号来补齐。
public static void main(String[] args) throws Exception {System.out.println(Base64.encode("1".getBytes()));System.out.println(Base64.encode("12".getBytes()));System.out.println(Base64.encode("123".getBytes()));// UTF-8编码下:一个汉字站3个字节System.out.println(Base64.encode("中国".getBytes("UTF-8")));// GBK编码下:一个汉字站2个字节System.out.println(Base64.encode("中国".getBytes("GBK")));}
MQ==
MTI=
MTIz
5Lit5Zu9
1tC5+g==
加密模式
ECB :
电子密码本, 需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密
可以并行处理数据,但同样的原文生成同样的密文, 不能很好的保护数据
CBC
密码块链接. 每个明文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有明文块
同样的原文生成的密文不一样,但串行处理数据速度慢
填充模式
当需要按块处理的数据的数据长度不符合块处理需求时, 会按照一定的方法规则填充满块
NoPadding:不填充
DES加密算法:要求原文长度必须是8byte的整数倍
AES加密算法: 要求原文长度必须是16byte的整数倍
PKCS5Padding:填充
数据块的大小为8位, 不够就补足
注意:
默认情况下, 加密模式和填充模式为 :
ECB/PKCS5Padding
。如果使用CBC模式, 在初始化Cipher对象时, 需要添加初始化向量IV参数 :IvParameterSpec iv = new IvParameterSpec(key.getBytes());
测试加密模式与填充模式
Cipher的加密类型如下:
public static void main(String[] args) throws Exception {// 原文String input = "Hello Word";// 使用des进行加密,密钥必须是8个字节String key = "12345678";// 获取Cipher对象的算法;如果没有指定加密模式和填充模式,默认值:ECB/PKCS5PaddingString transformation = "DES";// 指定获取密钥的算法String algorithm = "DES";String encrypt = encrypt(input, key, transformation, algorithm);System.out.println("加密:" + encrypt);String decrypt = dncrypt(encrypt, key, transformation, algorithm);System.out.println("解密:" + decrypt);}
bytes = �Rd��ʩ� h��
加密:01Jk6AecyqnqsABousAVIA==
解密:Hello Word
2.明确指定ECB加密模式和PKCS5Padding填充模式
public static void main(String[] args) throws Exception {// 原文String input = "Hello Word";// 使用des进行加密,密钥必须是8个字节String key = "12345678";// 获取Cipher对象的算法;如果没有指定加密模式和填充模式,默认值:ECB/PKCS5PaddingString transformation = "DES/ECB/PKCS5Padding";// 指定获取密钥的算法String algorithm = "DES";String encrypt = encrypt(input, key, transformation, algorithm);System.out.println("加密:" + encrypt);String decrypt = dncrypt(encrypt, key, transformation, algorithm);System.out.println("解密:" + decrypt);}
bytes = �Rd��ʩ� h��
加密:01Jk6AecyqnqsABousAVIA==
解密:Hello Word
3.明确指定ECB加密模式和NoPadding填充模式
此时原文必须为8byte的整数倍,否则报错:
Input length not multiple of 8 bytes
public static void main(String[] args) throws Exception {// 原文String input = "Hello Wo";// 使用des进行加密,密钥必须是8个字节String key = "12345678";// 获取Cipher对象的算法;如果没有指定加密模式和填充模式,默认值:ECB/PKCS5PaddingString transformation = "DES/ECB/NoPadding";// 指定获取密钥的算法String algorithm = "DES";String encrypt = encrypt(input, key, transformation, algorithm);System.out.println("加密:" + encrypt);String decrypt = dncrypt(encrypt, key, transformation, algorithm);System.out.println("解密:" + decrypt);}
bytes = �Rd��ʩ
加密:01Jk6Aecyqk=
解密:Hello Wo
4.明确指定CBC加密模式和PKCS5Padding填充模式
public static void main(String[] args) throws Exception {// 原文String input = "Hello Word";// 使用des进行加密,密钥必须是8个字节String key = "12345678";// 获取Cipher对象的算法;如果没有指定加密模式和填充模式,默认值:ECB/PKCS5PaddingString transformation = "DES/CBC/PKCS5Padding";// 指定获取密钥的算法String algorithm = "DES";String encrypt = encrypt(input, key, transformation, algorithm);System.out.println("加密:" + encrypt);String decrypt = dncrypt(encrypt, key, transformation, algorithm);System.out.println("解密:" + decrypt);}/** * 加密数据 */private static String encrypt(String input, String key, String transformation, String algorithm) throws Exception {// 获取加密对象Cipher cipher = Cipher.getInstance(transformation);// 指定秘钥规则:传入密钥的字节数组与指定的算法SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);// 初始向量,参数表示跟谁进行异或,初始向量的长度必须是8位IvParameterSpec ivParameterSpec = new IvParameterSpec("12345678".getBytes());// 初始化加密对象: 指定加密模式与秘钥规则cipher.init(Cipher.ENCRYPT_MODE, sks, ivParameterSpec);// 开始加密byte[] bytes = cipher.doFinal(input.getBytes());// 打印密文,由于bytes字节数字中存在负数,即ascii码有负数,解析不出来,将输出乱码System.out.println("bytes = " + new String(bytes));// 对字节数字进行Base64编码return Base64.encode(bytes);}/** * 解密数据 */private static String dncrypt(String input, String key, String transformation, String algorithm) throws Exception {// 获取Cipher对象Cipher cipher = Cipher.getInstance(transformation);// 指定秘钥规则:传入密钥的字节数组与指定的算法SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);// 初始向量,参数表示跟谁进行异或,初始向量的长度必须是8位IvParameterSpec ivParameterSpec = new IvParameterSpec("12345678".getBytes());// 初始化解密对象: 指定解密模式与秘钥规则cipher.init(Cipher.DECRYPT_MODE, sks, ivParameterSpec);// 解密byte[] bytes = cipher.doFinal(Base64.decode(input));return new String(bytes);}
bytes = �uQ�w�AоH~�q
加密:w3VRu3f3QdC+E0h+2gRxfw==
解密:Hello Word
```## 最后
从时代发展的角度看,网络安全的知识是学不完的,而且以后要学的会更多,同学们要摆正心态,既然选择入门网络安全,就不能仅仅只是入门程度而已,能力越强机会才越多。
因为入门学习阶段知识点比较杂,所以我讲得比较笼统,大家如果有不懂的地方可以找我咨询,我保证知无不言言无不尽,需要相关资料也可以找我要,我的网盘里一大堆资料都在吃灰呢。
干货主要有:
①1000+CTF历届题库(主流和经典的应该都有了)
②CTF技术文档(最全中文版)
③项目源码(四五十个有趣且经典的练手项目及源码)
④ CTF大赛、web安全、渗透测试方面的视频(适合小白学习)
⑤ 网络安全学习路线图(告别不入流的学习)
⑥ CTF/渗透测试工具镜像文件大全
⑦ 2023密码学/隐身术/PWN技术手册大全
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里**👉**[网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!](https://mp.weixin.qq.com/s/BWb9OzaB-gVGVpkm161PMw)
扫码领取
<img src="https://i-blog.csdnimg.cn/blog_migrate/08c3b846393bdaea6409358cbf194580.jpeg" />