내가 알고있는 한 documentation을 읽으면 AES 비밀 키를 만들고 싶다면 적어도 128 비트의 키로 알고리즘을 입력해야한다는 것을 이해합니다.
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
그래서 대신에 당신은 또한 SHA를 공급하기 위해 PBE 키를 사용하고있는 바이트를 얻을 수 있습니다
byte[] key = (Password+Username).getBytes("UTF-8"); // depends on your implementation
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // AES uses 16 byte of key as a parameter (?)
을 사용할 수 있습니다, 당신은 왜 PBE 키에서 128 개 비트를 얻기 주장 해 않는 키 생성 그런 식으로. Okey가 내 보안 폴더의 전체 작동 코드입니다. 문제가 해결되었습니다. 저에게 도움이되었으므로 언제든지 질문하십시오. 아래 코드에서 키가 pbeKeySpec을 사용하여 생성 된 것을 확인할 수 있습니다. 그러나 코드를 검토 할 때 나는 무엇이 잘못되었는지 알 수 없습니다.
public void testPBEWithSHA1AndAES() throws Exception {
String password = "test";
String message = "Hello World!";
byte[] salt = { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
(byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 };
byte[] iv = { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
(byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99,
(byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
(byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 };
int count = 1024;
// int keyLength = 256;
int keyLength = 128;
String cipherAlgorithm = "AES/CBC/PKCS5Padding";
String secretKeyAlgorithm = "PBKDF2WithHmacSHA1";
SecretKeyFactory keyFac = SecretKeyFactory
.getInstance(secretKeyAlgorithm);
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt,
count, keyLength);
SecretKey tmp = keyFac.generateSecret(pbeKeySpec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher ecipher = Cipher.getInstance(cipherAlgorithm);
ecipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv));
// decrypt
keyFac = SecretKeyFactory.getInstance(secretKeyAlgorithm);
pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, count,
keyLength);
tmp = keyFac.generateSecret(pbeKeySpec);
secret = new SecretKeySpec(tmp.getEncoded(), "AES");
// AlgorithmParameters params = ecipher.getParameters();
// byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
Cipher dcipher = Cipher.getInstance(cipherAlgorithm);
dcipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
byte[] encrypted = ecipher.doFinal(message.getBytes());
byte[] decrypted = dcipher.doFinal(encrypted);
assertEquals(message, new String(decrypted));
ByteArrayOutputStream out = new ByteArrayOutputStream();
CipherOutputStream cipherOut = new CipherOutputStream(out, ecipher);
cipherOut.write(message.getBytes());
StreamUtils.closeQuietly(cipherOut);
byte[] enc = out.toByteArray();
ByteArrayInputStream in = new ByteArrayInputStream(enc);
CipherInputStream cipherIn = new CipherInputStream(in, dcipher);
ByteArrayOutputStream dec = new ByteArrayOutputStream();
StreamUtils.copy(cipherIn, dec);
assertEquals(message, new String(dec.toByteArray()));
}
이 실행할 수 있습니다, 그러나, tmp.getEncoded() 항상 내가 아무리 소금이 무엇인지 내 질문에 언급하지 않고, 같은 비밀번호로 동일하다 같은 값을 반환합니다. – panda