我想使用Java的加密库来实现AES加密使用GCM模式(因为它是一个AEAD计划,我想确保数据完好无损),但我想喜欢使用用户友好的密码。让程序编译没有错误是一个困难,直到我几次抨击我的头墙砖墙,并阅读this other stackoverflow response.无法获取AES/GCM与密码
现在,不幸的是程序编译,但它返回的密文是字节数量的一小部分消息(我怀疑它只是GCM使用的标题,实际的消息根本没有被写入)。有人可以帮忙吗?
这里有一些程序变量:
private static final byte[] SALT = {(byte)0x3b,(byte)0x12,(byte)0x44,(byte)0x61,
(byte)0xec,(byte)0xc0,(byte)0xa1,(byte)0x82,
(byte)0x4d, (byte)0x97, (byte)0x4d, (byte)0x3c,
(byte)0x57, (byte)0xd9, (byte)0x94, (byte)0x52};
private static final String CIPHER_ALG = "AES/GCM/PKCS5Padding";
private static final String SEC_RANDOM_ALG = "SHA1PRNG";
private static final String S_KEY_FACTORY_ALG = "PBKDF2WithHmacSHA1";
private static final int AES_KEY_SIZE = 128; //num bits
private static final int GCM_NONCE_LENGTH = 16; //num bytes
private static final int GCM_TAG_LENGTH = 16; //num bytes
private static final int KEY_SPEC_ROUNDS = 65536;
这里是加密方法:
//FIXME somehow the cipher is truncating the message or something
private byte[] encrypt(File file, String password) throws IOException{
Path path = Paths.get(file.toURI());
byte[] messageBytes = Files.readAllBytes(path);
//Message bytes: 3253
System.out.printf("Message bytes: %d%n", messageBytes.length);
byte[] messageName = path.getFileName().toString().getBytes();
byte[] cipherBytes = {};
byte[] iv = {};
try{
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(S_KEY_FACTORY_ALG);
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), SALT, KEY_SPEC_ROUNDS, AES_KEY_SIZE);
SecretKey key = keyFactory.generateSecret(pbeKeySpec);
System.out.printf("Secret key take 1: " + Arrays.toString(key.getEncoded()) + "%n");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getEncoded(), "AES");
//FIXME this is not encrypting the message correctly
Cipher cipher = Cipher.getInstance(CIPHER_ALG);
final byte[] nonce = new byte[GCM_NONCE_LENGTH];
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(nonce);
GCMParameterSpec paramSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
iv = paramSpec.getIV();
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, paramSpec);
cipher.updateAAD(messageName);
cipher.update(messageBytes);
cipherBytes = cipher.doFinal();
}catch(NoSuchAlgorithmException e){
e.printStackTrace();
}catch(NoSuchPaddingException e){
e.printStackTrace();
}catch(InvalidKeyException e){
e.printStackTrace();
}catch(InvalidAlgorithmParameterException e){
e.printStackTrace();
}catch(InvalidKeySpecException e){
e.printStackTrace();
}catch(BadPaddingException e){
e.printStackTrace();
}catch(IllegalBlockSizeException e){
e.printStackTrace();
}
//IV bytes: 16
System.out.printf("IV bytes: %d%n", iv.length);
//Cipher bytes: 21
System.out.printf("Cipher bytes: %d%n", cipherBytes.length);
//Cipher bytes: [121, 68, 7, -69, -35, -9, -83, 101, -60, -80, 42, 59, -67, 126, 18, -82, 79, -60, 34, -125, 12]
System.out.printf("Cipher bytes: " + Arrays.toString(cipherBytes) + "%n");
//FIXME somehow the cipher is shortening the message or something
return cipherBytes;
}
你可能想看看我的[这个答案](http://stackoverflow.com/a/15712409/589259)关于加密相关的异常。 –