當我運行scrypt我第一次解密結果是正確的:Java的AES解密不同的結果保存並解密後,再次
哥哥人羣意味着之前完美眩光 憤怒某些傢伙古代需求社會
當我保存encryptedText,salt(例如到一個數據庫)並且想要解密時,我得到這個。
S,& 6;完美前人的傢伙古代社會需求怒瞪着一定
*更新 我認爲這個問題是我處理的方式數據(鹽和iv)。現在,我們可以加密並保存-encryptText,randomIV,randomSalt到數據庫並使用masterPassword解密而不會出現問題。
感謝您爲大家提供的幫助!
*編輯的代碼,我結束了這個解決方案
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.util.Random;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class Aes {
private static int pswdIterations = 65536;
private static int keySize = 256;
public static String encrypt(String plainText, String password, String salt, String initializationVector) throws
NoSuchAlgorithmException,
InvalidKeySpecException,
NoSuchPaddingException,
InvalidParameterSpecException,
IllegalBlockSizeException,
BadPaddingException,
UnsupportedEncodingException,
InvalidKeyException,
InvalidAlgorithmParameterException
{
byte[] saltBytes = salt.getBytes("UTF-8");
byte[] ivBytes = initializationVector.getBytes("UTF-8");
// Derive the key, given password and salt.
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(ivBytes));
byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
return new Base64().encodeAsString(encryptedTextBytes);
}
public static String decrypt(String encryptedText, String password, String salt, String initializationVector) throws
NoSuchAlgorithmException,
InvalidKeySpecException,
NoSuchPaddingException,
InvalidKeyException,
InvalidAlgorithmParameterException,
UnsupportedEncodingException
{
byte[] saltBytes = salt.getBytes("UTF-8");
byte[] ivBytes = initializationVector.getBytes("UTF-8");
byte[] encryptedTextBytes = new Base64().decodeBase64(encryptedText);
// Derive the key, given password and salt.
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
// Decrypt the message, given derived key and initialization vector.
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes));
byte[] decryptedTextBytes = null;
try {
decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return new String(decryptedTextBytes);
}
public String generateSalt() {
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[16];
random.nextBytes(bytes);
String s = new String(bytes);
return s;
}
public String generateIV(String chars, int length) {
Random rand = new Random();
StringBuilder buf = new StringBuilder();
for (int i=0; i<length; i++) {
buf.append(chars.charAt(rand.nextInt(chars.length())));
}
return buf.toString();
}
}
* Edited.Run測試
public static void main(String[] args) throws Exception {
//Passphrase and masterPassword
String passPhrase = "stackoverflow is great";
String masterPassword = "password";
//-Aes
Aes crypt = new Aes();
// Aes generate random salt
String genSalt = crypt.generateSalt();
String tmpSalt = genSalt;
// Aes generate random Iv
String genIV = crypt.generateIV("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 16);
String tmpIV = genIV;
// Aes encrypt phrase
String cipherPassPhrase = crypt.encrypt(passPhrase, masterPassword, tmpSalt, tmpIV);
System.out.println(cipherPassPhrase);
// save cipherPassPhrase, tmpSalt, tmpIV to database ....decrypt with not stored masterPassword
}
似乎是編碼problem.Try UTF-16.Bud仍然如果你只是使用普通的ASCII字符這shoud沒有發生。你的數據庫使用什麼編碼? –
這似乎是保存或檢索數據的問題。你能顯示相應的代碼嗎? – Henry
即使我不保存到數據庫它有這個問題。當我從控制檯取出salt字符串和加密字符串並解密時,它也顯示出這些不可讀的東西^^但是爲什麼80%的文本確定只有開始不行? – wook