1、前言
在【数据安全】一、数字签名、数字证书、数据加密这一章节中,我们实现了哈希算法(内容摘要)、对称加密算法、非对称加密算法。实现方式上,采用的是"java.security.*"包下的相关类,那么有没有更加简单的使用方式呢?有,接下来就介绍对应的工具类,hutool工具集的使用。
2、使用配置
建一个springboot项目,采用maven的形式引入hutool工具集,这里引入的版本是5.2.5
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
2、哈希算法
/**
* 1、使用sha1算法,从文件中,手动生成摘要
* */
@Test
void DigestFromFile() {
File file =new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\hash\\input.txt");
byte[] hash = SecureUtil.sha1().digest(file);
String d = "";
for (int i = 0; i < hash.length; i++)
{
int v = hash[i] & 0xFF;
if (v < 16) d += "0";
d += Integer.toString(v, 16).toUpperCase() + " ";
}
System.out.println(d);
}
/**
* 2、使用sha1算法,从文件中,自动生成摘要,结果与上一步相同
* */
@Test
void DigestHexFromFile() {
File file =new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\hash\\input.txt");
String hashResult = SecureUtil.sha1().digestHex(file);
System.out.println(hashResult);
}
/**
* 3、使用sha1算法,从字符串内容中,手动生成摘要。虽然字符串内容相同,结果与第1步不同
* */
@Test
void DigestFromString(){
byte[] hash = SecureUtil.sha1().digest("Upon my death, my property shall be divided equally among my children; however, my son George shall receive nothing.");
String d = "";
for (int i = 0; i < hash.length; i++)
{
int v = hash[i] & 0xFF;
if (v < 16) d += "0";
d += Integer.toString(v, 16).toUpperCase() + " ";
}
System.out.println(d);
}
/**
* 4、使用sha1算法,从字符串内容中,自动生成摘要。结果与第3步相同
* */
@Test
void DigestHexFromString(){
String hashResult = SecureUtil.sha1().digestHex("Upon my death, my property shall be divided equally among my children; however, my son George shall receive nothing.");
System.out.println(hashResult);
}
3、对称加密算法
/**
* 5、生成对称密码,并输出到密码文件
* */
@Test
void AESGenerateKeyFile() throws FileNotFoundException,IOException{
SecretKey key = SecureUtil.generateKey("AES");
File file = new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\secret.key");
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file)))
{
out.writeObject(key);
}
}
/**
* 6、使用对称算法AES,以及对称密码加密文件。注意将key转换为byte[]数组的方式
* */
@Test
void AESEncryptFromKeyFile() throws ClassNotFoundException,FileNotFoundException,IOException{
File keyfile = new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\secret.key");
File plaintextFile =new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\plaintext.txt");
File encryptedFile =new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\encrypted.txt");
try (ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(keyfile));
InputStream in = new FileInputStream(plaintextFile);
OutputStream out = new FileOutputStream(encryptedFile))
{
SecretKey key = (SecretKey) keyIn.readObject();
byte[] keyStream = IoUtil.readBytes(new FileInputStream(keyfile));
AES aes = SecureUtil.aes(key.getEncoded());
byte[] encryptStream = aes.encrypt(in);
out.write(encryptStream);
}
}
/**
* 7、使用对称算法AES,以及对称密码解密文件。
* */
@Test
void AESDescryptFromFile() throws ClassNotFoundException,FileNotFoundException,IOException{
File keyfile = new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\secret.key");
File encryptedFile =new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\encrypted.txt");
File plaintextFile =new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\plaintext.txt");
try (ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(keyfile));
InputStream in = new FileInputStream(encryptedFile);
OutputStream out = new FileOutputStream(plaintextFile))
{
SecretKey key = (SecretKey) keyIn.readObject();
AES aes = SecureUtil.aes(key.getEncoded());
byte[] decryptStream = aes.decrypt(in);
out.write(decryptStream);
}
}
4、非对称加密算法
/**
* 8、生成非对称算法RSA公私钥加密对
* */
@Test
void RSAGenerateKeyPair() throws ClassNotFoundException,FileNotFoundException,IOException{
KeyPair keyPair = SecureUtil.generateKeyPair("RSA");
File publicKeyFile= new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\publickey.key");
File privateKeyFile = new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\privatekey.key");
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(publicKeyFile)))
{
out.writeObject(keyPair.getPublic());
}
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(privateKeyFile)))
{
out.writeObject(keyPair.getPrivate());
}
}
/**
* 9、使用非对称算法RSA,以及公钥,加密文件
* */
@Test
void RSAEncodedFile() throws IOException,ClassNotFoundException{
File publicKeyFile=new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\publickey.key");
File rsaEncryptedFile=new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\rsaencrypted.txt");
File rsaplaintextFile=new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\rsaplaintext.txt");
// 使用RSA公共密钥对AES密钥进行加密
try (ObjectInputStream publickeyIn = new ObjectInputStream(new FileInputStream(publicKeyFile));
DataOutputStream out = new DataOutputStream(new FileOutputStream(rsaEncryptedFile));
InputStream in = new FileInputStream(rsaplaintextFile) )
{
Key publicKey = (Key) publickeyIn.readObject();
RSA rsa = SecureUtil.rsa(null, publicKey.getEncoded());
byte[] encryptedStream = rsa.encrypt(in, KeyType.PublicKey);
out.write(encryptedStream);
}
}
/**
* 10、使用非对称算法RSA,以及私钥,解密文件
* */
@Test
void RSADecodedFile() throws IOException,ClassNotFoundException{
File privateKeyFile = new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\privatekey.key");
File rsaEncryptedFile=new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\rsaencrypted.txt");
File rsadecryptedFile=new File("D:\\open source\\gitee\\corejava\\labs-v2ch09\\rsadecrypted.txt");
// 使用RSA公共密钥对AES密钥进行加密
try (ObjectInputStream privatekeyIn = new ObjectInputStream(new FileInputStream(privateKeyFile));
DataOutputStream out = new DataOutputStream(new FileOutputStream(rsadecryptedFile));
InputStream in = new FileInputStream(rsaEncryptedFile) )
{
Key privateKey = (Key) privatekeyIn.readObject();
RSA rsa = SecureUtil.rsa(privateKey.getEncoded(), null);
byte[] decryptedStream = rsa.decrypt(in, KeyType.PrivateKey);
out.write(decryptedStream);
}
}
以上代码都有比较详细的说明,故不再细述。
源码参考:https://gitee.com/muziye/core-java.git 参考“labs-v2ch09-tool”章节
相关参考:如何将SecretKey转化为byte[],或者String字符串