给出以下示例:
String f="A000000000000000";
FileInputStream fis = new FileInputStream("C:\\Users\\original.txt");
byte[] bytes = DatatypeConverter.parseHexBinary(f);
SecretKey key = new SecretKeySpec(bytes, 0, bytes.length, "DES");
String strDataToEncrypt = new String();
String strCipherText = new String();
String strDecryptedText = new String();
try{
Cipher desCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
desCipher.init(Cipher.ENCRYPT_MODE,key);
//read from file and transform to String
try{
builder = new StringBuilder();
int ch;
while((ch = fis.read()) != -1){
builder.append((char)ch);
}
}catch (IOException e){
}
byte[] byteDataToEncrypt = builder.toString().getBytes();
byte[] byteCipherText = desCipher.doFinal(byteDataToEncrypt);
strCipherText = new BASE64Encoder().encode(byteCipherText);
System.out.println(strCipherText);
每次使用相同的密钥值i编译时,加密数据都不同,我尝试了不同的代码,加密数据总是一样的,这里有什么问题?
答案 0 :(得分:2)
documentation for javax.crypto.Cipher.init部分说:
如果此密码需要任何不能的算法参数 从给定密钥派生,底层密码实现是 应该自己生成所需的参数(使用 特定于提供者的默认值或随机值)
DES CBC(密码块链接)模式需要初始化向量(IV)。如果你没有提供一个(你不应该提供,因为它打开你最多dictionary attacks),将生成一个随机的。
但是如果您希望每次加密数据都相同,则需要使用IvParameterSpec
指定IV:
byte[] iv = DatatypeConverter.parseHexBinary("0000000000000000");
IvParameterSpec ips = new IvParameterSpec(iv);
desCipher.init(Cipher.ENCRYPT_MODE, key, iv);
如果您确实让它生成随机IV,您可以使用desCipher.getIV()
检索生成的IV。