对称加密是一种加密算法,它和非对称加密的区别在于:加密和解密使用不同的密钥,对称加密使用同一个密钥对数据进行加密和解密。 今天我们来学习下对称加密的实现方法,不需要使用到私钥,只需要用到公钥。 首先我们来看下这个加密解密的过程: 我们先来看下输入参数,这里使用了公钥密码来进行对称加密: 输出结果为: 在此基础上,我们再来看下这个对称加密的算法: 通过上面的代码可以看出,要想进行解密需要先解密公钥,然后再用私钥进行解密。
-
1、使用公钥来加密数据
使用公钥加密的原理是,数据长度固定,使用密钥将数据加密。例如,如果要对1-8位的数字进行加密,则需要使用32位的密钥。首先生成32位的密钥,然后对其进行加密得到256位的数据。最后,将数据保存到一个字符串中,然后将该字符串发送到接收方。 使用公钥加密后,就相当于给数据加上了一个密码。如果想要对数据进行解密,就需要解密公钥并将其还原成原来的内容。 在上面的代码中,使用了4个字符: 在这里我们需要注意下参数 name中的a和b,在没有密钥的情况下是无法对其进行加密的。公钥的长度固定为32位,所以我们需要使用32位的密钥才能对数据进行加密。 使用公钥进行加密后,我们还需要对数据进行解密才能得到原来的内容。这里可以通过发送一段伪随机数来实现解密,伪随机数是由16位随机数和64位随机数组合而成:
-
2、生成对称密钥
我们知道,加密和解密是通过不同的密钥来完成的,对称密钥就是加密和解密的钥匙。生成对称密钥就是使用私钥,然后用公钥去加密数据。所以我们需要找到一个对称密钥生成算法,通过这个算法来生成对称密钥。我们在 Java中找到了一个生成对称密钥的算法: 这里我们使用了 RSA算法,使用 RSA算法来计算公钥密码。RSA算法是基于大数分解的一种计算方法,由美国国家科学基金会于1986年提出,并于1987年通过了美国国家标准与技术研究院(NIST)的评审。 RSA算法有两个参数,一个是私钥,另一个是公钥。从上面的代码中我们可以看出, RSA算法需要两个参数:公钥和私钥。也就是说,我们需要找到一个私钥和一个公钥。下面我们来看下具体的实现过程: 第一步:获取公钥:首先在官网上找到 RSA算法,然后点击“免费下载”。 第二步:下载并解压 RSA文件 第三步:使用 RSA算法生成私钥:然后我们使用一个`. java. lang`文件来生成一个`. java. lang`文件(注意这里使用的是 java)。 第四步:使用 java. lang把`. java. lang`文件里面的`write_key’`替换为`write_primes’。 第五步:获取公钥并加密:然后将此密钥对数据进行加密(这里需要注意一下,我们需要使用的是公钥,不是私钥) 第六步:使用私钥解密:最后将此密钥对数据进行解密。 上面的代码中使用了三个参数,其中第一个参数是私钥值,第二个参数是公钥值,最后一个参数是加密和解密的公钥。通过上面的代码可以看出,我们先使用了私钥对数据进行加密,然后再将加密后的数据和原来的数据进行对比。结果如下:
-
3、解密数据
这个时候,我们可以使用以下方法进行解密: 使用 path ()方法获取公钥,并使用 path ()方法获取私钥。 其中 path ()方法的参数为:公钥; 我们可以发现,这里的密钥长度是50,这就说明了要想进行加密,需要至少50个字符才能完成。 这里我们使用了字符串来作为输入参数,因为字符串是不可能进行加密的,所以它可以用来做解密操作。 在上面的代码中,我们采用了两个函数分别对数据进行解密。 第一个函数是用来对数据进行加密的,第二个函数是用来解密数据的。当然在实际工作中,我们只需要解密第一个函数即可。
-
4、验证加密的结果
当我们完成了密码的生成,加密,解密等操作之后,接下来我们就需要验证下加密的结果是否正确,可以通过以下几种方式来验证: (1)查看输入的参数是否和返回的参数相同,如果相同则说明是正确的,如果不相同则说明没有正确加密; (2)我们可以通过查看参数的返回类型来验证是否正确,比如: 我们可以使用 javac. append ()方法将返回类型转换为数字签名: (3)使用 java. util. toString ()方法将返回类型转换为字符串: 可以看出,上面几种验证方式都是需要将返回的类型进行转换的,但是不管是哪种方法都需要在编译期完成。这也是为什么我们不建议大家在程序运行时进行转换类型的原因。 那么上面我们说了这么多怎么去使用对称加密来实现呢?接下来我们来看下实现对称加密的核心原理: 通过上面这段代码,我们可以看出,这里使用了两个私钥(公钥)来对数据进行加密和解密。但是这里有个问题:为什么要使用两个私钥来进行加密呢?因为一个私钥只能处理一个数字签名,如果有多个数字签名,那么私钥就不能处理了。 这就需要使用两个公钥了,一个公钥是公开的,另一个公钥是保密的。通过上面这段代码我们就可以很好地理解对称加密的原理了。 以上就是今天所讲到的内容了,相信通过这段话大家已经对对称加密有了一定的了解。如果还有什么不明白或者不懂的地方请留言。
-
5、总结
在实际项目中,我们会使用到对称加密和非对称加密两种加密方式,如果不考虑速度的话,我们建议使用非对称加密。 如果是考虑速度的话,建议使用对称加密,因为它的算法简单、占用资源小、效率高。但是对称加密会存在一些问题: 1.当客户端不知道公钥的时候,无法对数据进行解密; 2.私钥的安全等级不如公钥高; 3.私钥不能存储在客户端; 4.当客户端被攻击时,可能会造成数据泄露。 因此,在实际应用中,建议使用非对称加密方式。
以下是常用的Java对称加密代码:
1. AES加密
```java
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class AESUtil {
private static final String KEY = "1234567890123456"; // 密钥
public static String encrypt(String content) throws Exception {
SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedBytes = cipher.doFinal(content.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String content) throws Exception {
SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedBytes = Base64.getDecoder().decode(content);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
return new String(decryptedBytes, "UTF-8");
}
}
```
2. DES加密
```java
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class DESUtil {
private static final String KEY = "12345678"; // 密钥
public static String encrypt(String content) throws Exception {
SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedBytes = cipher.doFinal(content.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String content) throws Exception {
SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedBytes = Base64.getDecoder().decode(content);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
return new String(decryptedBytes, "UTF-8");
}
}
```
3. Blowfish加密
```java
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class BlowfishUtil {
private static final String KEY = "1234567890123456"; // 密钥
public static String encrypt(String content) throws Exception {
SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedBytes = cipher.doFinal(content.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String content) throws Exception {
SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedBytes = Base64.getDecoder().decode(content);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
return new String(decryptedBytes, "UTF-8");
}
}
```