由于近期的要写一个对称加密的module,遇到一些问题,在此做个笔记
AES 256原生Java jdk not support it. 需要替换掉其中的lib 下secret 里的两个将jar,此处百度十分好找,自行查找。
1.生成keyStore 文件,由于使用的是AES256位的key,使用jce提供的 jceks 文件格式。
keytool -genseckey -keystore c:\UserKeyStore.jceks -storetype jceks -storepass AESCrypto -keyalg AES -keysize 256 -alias jceksaes
会提示别称jecksaes的key的密码是否和keystore的密码是否一致。为了安全考虑,keystore的访问是需要密码的,key的访问也需要密码,因为一个keystore可能存储多个key,每个key的存储格式为 entry 类似。
c:\UserKeyStore.jceks 生成在c盘根目录下。
AESCrypto -storepass此处是访问keystore的密码
jceksaes -alias 参数后跟的是生成的key的别称
2.查了很多文档都没有详细说明当使用 keytool 工具修改keystore密码的command,多数都会报错。因为格式是jce的,所以有些问题。
keytool -storetype jceks -storepasswd -new 123456 -keystore c:\UserKeyStore.jceks -storepass AESCrypto
修改keystore 的密码从AESCrypto 换成 123456 ,多次报错的原因是因为storetype jceks没有带上,导致keytool工具认生。
3.使用keytool工具修改key 的password.
keytool -storetype jceks -keypasswd -alias jceksaes -new 654321 -keypass AESCrypto -keystore c:\UserKeyStore.jceks -storepass 123456
4.keytool read keystore ,同样加上参数-storetype jceks 后加上
package com.alions;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Test;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AES256{
public static boolean initialized = false;
public static final String ALGORITHM = "AES/ECB/PKCS7Padding";
/**
* @param String str 要被加密的字符串
* @param byte[] key 加/解密要用的长度为32的字节数组(256位)密钥
* @return byte[] 加密后的字节数组
*/
public static String Aes256Encode(String str, byte[] key){
initialize();
byte[] result = null;
String encoded=null;
try{
Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); //生成加密解密需要的Key
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
result = cipher.doFinal(str.getBytes("UTF-8"));
BASE64Encoder encoder = new BASE64Encoder();
encoded = encoder.encode(result);
}catch(Exception e){
e.printStackTrace();
}
return encoded;
}
/**
* @param byte[] bytes 要被解密的字节数组
* @param byte[] key 加/解密要用的长度为32的字节数组(256位)密钥
* @return String 解密后的字符串
*/
public static String Aes256Decode(String encryptionStr, byte[] key){
initialize();
String result = null;
try{
Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); //生成加密解密需要的Key
cipher.init(Cipher.DECRYPT_MODE, keySpec);
BASE64Decoder decoder = new BASE64Decoder();
byte[] bytes = decoder.decodeBuffer(encryptionStr);
byte[] decoded = cipher.doFinal(bytes);
result = new String(decoded, "UTF-8");
}catch(Exception e){
e.printStackTrace();
}
return result;
}
public static void initialize(){
if (initialized) return;
Security.addProvider(new BouncyCastleProvider());
initialized = true;
}
/***\
* 存储当前的key
*/
private String pwd="AESCrypto";
@Test
public void saveUserKey(){
try{
File keyStorefile =new File("./UserKeyStore.jceks");
KeyStore keyStore = KeyStore.getInstance("JCEKS");
//create a new the paremete is null , pwd is null
if(AES256.isFileExists(keyStorefile)){
keyStore.load(new FileInputStream(keyStorefile), pwd.toCharArray());
}else{
//新建
keyStore.load(null, null);
}
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
String password="admin";
keyGen.init(256,new SecureRandom(password.getBytes()));
Key key=keyGen.generateKey();
byte[] enCodeFormat = key.getEncoded();
System.out.println(enCodeFormat.length);
//Ss/jICpf9c9GeJj8WKqx1hUClEEELCSL9GF/s23xx5M=
String strTempKey=Base64.getEncoder().encodeToString(enCodeFormat);
System.out.println(strTempKey);
System.out.println(strTempKey.length());
keyStore.setKeyEntry("TMOKey", key, "AESCrypto".toCharArray(), null);
keyStore.store(new FileOutputStream(keyStorefile), pwd.toCharArray());
}catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* get the key from the key store
* keytool -genseckey -keystore UserKeyStore.jceks -storetype jceks -storepass AESCrypto -keyalg AES -keysize 256 -alias jceksaes
*
* AESCrypto keystore的存储密钥
*
*/
@Test
public void getKeyFromKeyStore(){
try{
File keyStorefile =new File("./UserKeyStore.jceks");
KeyStore keyStore = KeyStore.getInstance("JCEKS");
if(AES256.isFileExists(keyStorefile)){
keyStore.load(new FileInputStream(keyStorefile),"AESCrypto".toCharArray());
}else{
throw new Exception("No UserKeyStore.JCEKS exists");
}
//Mb25QS0ytWTjzybaBgk4kNx8fzw/ClxsAIyYQJBBFSQ=
Key key = keyStore.getKey("jceksaes", "AESCrypto".toCharArray());
byte[] enCodeFormat = key.getEncoded();
System.out.println(enCodeFormat.length);
String strTempKey=Base64.getEncoder().encodeToString(enCodeFormat);
System.out.println(strTempKey.toString());
}catch(Exception ex){
ex.printStackTrace();
}
}
// 判断文件夹是否存在
public static void judeDirExists(File file) {
if (file.exists()) {
if (file.isDirectory()) {
System.out.println("dir exists");
} else {
System.out.println("the same name file exists, can not create dir");
}
} else {
System.out.println("dir not exists, create it ...");
file.mkdir();
}
}
// 判断文件是否存在
public static boolean isFileExists(File file) {
if (file.exists()) {
System.out.println("file exists");
return true;
} else {
System.out.println("file not exists, create it ...");
return false;
}
}
// public static void main(String agrs[]){
// byte[] keys={33, 34, 35, 36, 37, 38, 39, 40, 4, 42, 43, 44, 45, 46, 47, 58, 59, 60, 6, 62, 63, 64, 9, 92, 93, 94, 95, 96, 23, 24, 25, 26};
// String str="i love dsgfsdsf life";
// String resultBytes=AES256.Aes256Encode(str, keys);
// System.out.println("this is the clear text:" +str);
// System.out.print("this is after encryption word: ");
// //print the resultKey array
// System.out.println(resultBytes);
//
// System.out.print("this is the word after decryption :");
// String decryptionStr=AES256.Aes256Decode(resultBytes, keys);
// System.out.println(decryptionStr);
//
// }
}
附上一段java代码,本人测试使用