每条记录使用单独的秘钥,通过AES CBC算法进行加密。
使用统一的派生密钥,使用每条记录的ID号作为派生密钥的信息进行密钥派生。
得到派生密钥之后,就可以使用AES算法进行密钥派生。
3. 使用方法
1. 派生密钥
byte[] key=deriveAesKey("123");
派生完的密钥在byte数组key中。
2. 加密 byte[] encryptedData = aesCbcEncrypt(key, "Hello".getBytes() ); 使用上面的密钥进行加密。“Hello”是要加密的内容。返回值为byte数组,为加密后的内容。可以转码后进行保存(进数据库)。
3. 解密
byte[] decryptedData = aesCbcDecrypt(key, encryptedData);
解密完的数据为byte数组。请根据需要进行转码。例如:new String(decryptedData)。
4. 限制
需要对JDK进行JCE Unlimited Policy补丁(可以从Oracle网站下载)。
5. 附录:相关代码
加密函数
final
static
int
AES_KEY_LENGTH =
32
;
// 864273525a44818245d9c4910c8c9ab7
final
static
byte
[] saltConst = {(
byte
)
0x86
,(
byte
)
0x42
,(
byte
)
0x73
,(
byte
)
0x52
,(
byte
)
0x5A
,(
byte
)
0x44
,(
byte
)
0x81
,(
byte
)
0x82
,
(
byte
)
0x45
,(
byte
)
0xD9
,(
byte
)
0xC4
,(
byte
)
0x91
,(
byte
)
0x0C
,(
byte
)
0x8C
,(
byte
)
0x9A
,(
byte
)
0xB7
};
// 82ef6e6ecfe49e4084355995e42293ec
final
static
byte
[] ivConst = {(
byte
)
0x82
,(
byte
)
0xEF
,(
byte
)
0x6E
,(
byte
)
0x6E
,(
byte
)
0xCF
,(
byte
)
0xE4
,(
byte
)
0x9E
,(
byte
)
0x40
,
(
byte
)
0x84
,(
byte
)
0x35
,(
byte
)
0x59
,(
byte
)
0x95
,(
byte
)
0xE4
,(
byte
)
0x22
,(
byte
)
0x93
,(
byte
)
0xEC
};
final
static
IvParameterSpec ivConstParams=
new
IvParameterSpec(ivConst);
public
static
byte
[] deriveAesKey(String password) {
int
iterations =
3
;
char
[] chars = password.toCharArray();
byte
[] salt = saltConst;
byte
[] hash =
null
;
PBEKeySpec spec =
new
PBEKeySpec(chars, salt, iterations, AES_KEY_LENGTH *
8
);
SecretKeyFactory skf;
try
{
skf = SecretKeyFactory.getInstance(
"PBKDF2WithHmacSHA1"
);
hash = skf.generateSecret(spec).getEncoded();
}
catch
(NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch
(InvalidKeySpecException e) {
e.printStackTrace();
}
return
hash;
}
public
static
byte
[] aesCbcEncrypt(
byte
[] key,
byte
[] source) {
try
{
Cipher cipher;
SecretKeySpec skeySpec =
new
SecretKeySpec(key,
0
, key.length,
"AES"
);
cipher = Cipher.getInstance(AES_CBC);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivConstParams);
//
cipher.update(source,
0
, source.length);
byte
[] out = cipher.doFinal(
source,
0
, source.length
);
return
out;
}
catch
(NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
catch
(InvalidKeyException e) {
e.printStackTrace();
}
catch
(IllegalBlockSizeException e) {
e.printStackTrace();
}
catch
(BadPaddingException e) {
e.printStackTrace();
}
catch
(InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return
null
;
}
public
static
byte
[] aesCbcDecrypt(
byte
[] key,
byte
[] source) {
try
{
Cipher cipher;
SecretKeySpec skeySpec =
new
SecretKeySpec(key,
0
, key.length,
"AES"
);
cipher = Cipher.getInstance(AES_CBC);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivConstParams);
byte
[] out = cipher.doFinal(
source,
0
, source.length
);
return
out;
}
catch
(NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
catch
(InvalidKeyException e) {
e.printStackTrace();
}
catch
(IllegalBlockSizeException e) {
e.printStackTrace();
}
catch
(BadPaddingException e) {
e.printStackTrace();
}
catch
(InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return
null
;
}
public
static
void
main(String args[]){
// System.out.println( md5("123") );
// System.out.println( sha("123") );
System.out.println(byte2hex(deriveAesKey(
"123"
)));
System.out.println(byte2hex(deriveAesKey(
"1234"
)));
byte
[] key=deriveAesKey(
"123"
);
byte
[] encryptedData = aesCbcEncrypt(key,
"Hello"
.getBytes() );
System.out.println(byte2hex(encryptedData));
byte
[] decryptedData = aesCbcDecrypt(key, encryptedData);
System.out.println(
new
String(decryptedData));
}
|