AES对称加密 及 KeyStore 数据存储与读取
- AES 对称加解密
- KEYSTORE 存储读取信息
- KEYSTORE 存储读取秘钥信息
- 相关导入
AES 对称加解密
/**
* AES 对称加密、解密测试
*/
public static void aesTest() {
String plainText = "TCBJ-SECRET-KEY-ENCODE-DECODE-TEST";
try {
// 生成秘钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
/**
* todo
* 根据业务保存秘钥,秘钥一旦变化旧的内容无法解密
*/
// 加密
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encrypted = cipher.doFinal(plainText.getBytes());
// 解密
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decrypted = cipher.doFinal(encrypted);
System.out.println("输入:" + plainText);
System.out.println("加密结果:" + new String(encrypted));
System.out.println(decrypted);
System.out.println("解密结果:" + new String(decrypted));
} catch (Exception e) {
System.out.println("AES 加解密异常");
}
}
KEYSTORE 存储读取信息
此处的keystore文件是用命令生成的,密码在命令中就定义了
不想用命令生成也可以在代码中直接生成
具体执行路径:JDK安装目录的 /bin 下 打开cmd 窗口
jceks 记得写对
keytool -genkey -alias csdn -keypass 123456 -keyalg RSA -keysize 1024 -validity 3650 -keystore D:/keyStore/test.keystore -storepass 888999 -storetype jceks
存储普通数据
/**
* keystore 文件秘钥存储测试
*/
public static void keyStoreTest() {
FileInputStream inputStream = null ;
OutputStream outputStream = null;
try {
// 读取 keyStore 文件转换为 keyStore 密钥库对象
inputStream = new FileInputStream("D:\\keyStore\\test.keystore");
// 设置证书类型 jceks
KeyStore keyStore = KeyStore.getInstance("jceks");
// 设置密钥库密码——获取keystore信息所需的密码
String storepass = "888999";
keyStore.load(inputStream,storepass.toCharArray());
inputStream.close();
// 加载keystore,就可以读取keystore现有条目、或者写入新条目
// 别名——创建文件指定好的别名及密码
String alias = "csdn";
// 别名密码,指定别名条目的密码——私钥密码
String keypass = "123456";
KeyStore.ProtectionParameter parameter = new KeyStore.PasswordProtection(keypass.toCharArray());
KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias,parameter);
PrivateKey myPrivateKey = entry.getPrivateKey();
System.out.println("获取到的私钥是:" + myPrivateKey.toString());
// 设置秘钥信息别名 desPws 及 访问密码 decrp pws ,写入存储信息 desPwd
String desPwd = "我是存储在 keystore 中的 AES 加密解密用的秘钥4.0";
String password = "decryp pws";
SecretKey mySecretKey = new SecretKeySpec(desPwd.getBytes(),"JKS");
KeyStore.SecretKeyEntry skEntry = new KeyStore.SecretKeyEntry(mySecretKey);
keyStore.setEntry("desPws", skEntry, new KeyStore.PasswordProtection(password.toCharArray()));
// 将 keystore 存储到指定输出流,并用密码保护完整性
outputStream = new FileOutputStream("D:\\keyStore\\test.keystore");
keyStore.store(outputStream,storepass.toCharArray());
outputStream.close();
} catch (Exception e) {
// todo 存储 keyStore 文件失败
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
// todo 关闭文件流失败
}
}
}
读取普通数据
/**
* keystore 文件秘钥提取测试
*/
public static void keyStoreDecodeTest() {
String storepass = "888999";
try {
FileInputStream inputStream = null;
// 读取keystore文件转换为 keystore 密钥库对象
inputStream = new FileInputStream("D:\\keyStore\\test.keystore");
// 设置证书类型
KeyStore keyStore = KeyStore.getInstance("jceks");
// 使用密钥库密码访问
keyStore.load(inputStream,storepass.toCharArray());
inputStream.close();
// 根据别名,从 证书获取密码并解密
// keystore.getKey 返回与给定别名关联的秘钥,并用给定密码来恢复他
String password = "decryp pws";
Key key = keyStore.getKey("desPws",password.toCharArray());
// key.getEncode 返回基本编码格式的秘钥,如果秘钥不支持编码,返回null
// 注意这里存储的是字符串,所以要根据 encode 转化,如果存储的是 SecretKey 直接 key 的值就是了
System.out.println("从证书中获取的秘钥为:" + new String(key.getEncoded()));
} catch (Exception e) {
// todo 异常处理
}
}
KEYSTORE 存储读取秘钥信息
这里跟存储、读取普通数据其实差不多,多了一个生成 keystore 文件步骤而已
读取的时候 key 直接就是对应存储的 secretKey了
/**
* AES 秘钥对象 SecretKey 存储 KeyStore 中
*/
public static void saveSecretKey2KeyStore() {
try {
// 生成秘钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
KeyStore keyStore = KeyStore.getInstance("jceks");
keyStore.load(null,null);
System.out.println("保存的秘钥:" + secretKey);
// 可以存字符串也可以存对象
KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey);
// 设置条目名称及密码
String entryPwd = "abc";
keyStore.setEntry("test",secretKeyEntry,new KeyStore.PasswordProtection(entryPwd.toCharArray()));
FileOutputStream outputStream = new FileOutputStream("D:\\keyStore\\test2.keystore");
// 设置文件访问密码
String storepwd = "123456";
keyStore.store(outputStream,storepwd.toCharArray());
outputStream.close();
} catch (Exception e) {
// todo
}
}
/**
* 从 KeyStore 获取 AES 秘钥对象 SecretKey
*/
public static void getSecretKeyFromKeyStore() {
try {
String storepass = "123456";
FileInputStream inputStream = new FileInputStream("D:\\keyStore\\test2.keystore");
KeyStore keyStore1 = KeyStore.getInstance("jceks");
keyStore1.load(inputStream,storepass.toCharArray());
inputStream.close();
String password = "abc";
Key key = keyStore1.getKey("test",password.toCharArray());
SecretKey keyValue = (SecretKey) key;
System.out.println("获取到的秘钥:" + keyValue);
} catch (Exception e) {
// todo
}
}
相关导入
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;