我仍在寻找解决加密需求的好方法。我在互联网上找到了一个解决方案,我重新设计以满足程序需求,但加密失败了。我不知道为什么。有什么建议吗?
亲爱的Maarten Bodeswes我尝试了你的解决方案,但无法让它稳定运行。我通过php将加密数据发送到数据库并通过php将其恢复。我想我必须用其他东西交换加号,但它仍然不会稳定运行。
import java.io.IOException;
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.security.spec.KeySpec;
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;
public class AESplus
{
// AES specification
private static final String CIPHER_SPEC = "AES/CBC/PKCS5Padding";
// Key derivation specification
private static final String KEYGEN_SPEC = "PBKDF2WithHmacSHA1";
private static final int SALT_LENGTH = 16; // in bytes
private static final int ITERATIONS = 32768;
private static final int KEY_LENGTH = 128;
private static final String SPLITCHAR = "###";
public static SecretKey makeKey(String kennwort) throws NoSuchAlgorithmException, InvalidKeySpecException
{
char[] password = kennwort.toCharArray();
// generate salt
byte[] salt = generateSalt(SALT_LENGTH);
SecretKeyFactory factory = SecretKeyFactory.getInstance(KEYGEN_SPEC);
KeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH);
SecretKey tmp = factory.generateSecret(spec);
return tmp;
}
private static byte[] generateSalt(int length)
{
Random r = new SecureRandom();
byte[] salt = new byte[length];
r.nextBytes(salt);
return salt;
}
public static String encrypt(String input, SecretKey key) throws InvalidKeyLengthException, StrongEncryptionNotAvailableException,
IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException,
IllegalBlockSizeException, BadPaddingException
{
StringBuilder output = new StringBuilder();
// initialize AES encryption
Cipher encrypt = null;
encrypt = Cipher.getInstance(CIPHER_SPEC);
encrypt.init(Cipher.ENCRYPT_MODE, key);
// get initialization vector
byte[] iv = encrypt.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
byte[] encrypted = encrypt.update(input.getBytes());
output.append(HexUtils.toHex(encrypted));
encrypted = encrypt.doFinal();
if (encrypted != null)
{
// write authentication and AES initialization data
output.append(HexUtils.toHex(iv) + SPLITCHAR);
// data
output.append(HexUtils.toHex(encrypted));
}
return output.toString();
}
public static String decrypt(String input, SecretKey schlüssel) throws InvalidPasswordException, InvalidAESStreamException,
IOException, StrongEncryptionNotAvailableException, NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
{
String[] inputArray = input.split(SPLITCHAR);
// initialize AES decryption
byte[] iv = new byte[16]; // 16-byte I.V. regardless of key size
iv = HexUtils.toBytes(inputArray[0]);
Cipher decrypt = Cipher.getInstance(CIPHER_SPEC);
decrypt.init(Cipher.DECRYPT_MODE, schlüssel, new IvParameterSpec(iv));
// read data from input into buffer, decrypt and write to output
byte[] hexInput = HexUtils.toBytes(inputArray[1]);
byte[] decrypted = decrypt.update(hexInput);
StringBuilder output = new StringBuilder();
output.append(new String(decrypted));
// finish decryption - do final block
decrypted = decrypt.doFinal();
if (decrypted != null)
{
output.append(new String(decrypted));
}
return output.toString();
}
// ******** EXCEPTIONS thrown by encrypt and decrypt ********
/**
* Thrown if an attempt is made to decrypt a stream with an incorrect
* password.
*/
public static class InvalidPasswordException extends Exception
{
private static final long serialVersionUID = 1L;
}
/**
* Thrown if an attempt is made to encrypt a stream with an invalid AES key
* length.
*/
public static class InvalidKeyLengthException extends Exception
{
private static final long serialVersionUID = 1L;
InvalidKeyLengthException(int length)
{
super("Invalid AES key length: " + length);
}
}
/**
* Thrown if 192- or 256-bit AES encryption or decryption is attempted,
* but not available on the particular Java platform.
*/
public static class StrongEncryptionNotAvailableException extends Exception
{
private static final long serialVersionUID = 1L;
public StrongEncryptionNotAvailableException(int keySize)
{
super(keySize + "-bit AES encryption is not available on this Java platform.");
}
}
/**
* Thrown if an attempt is made to decrypt an invalid AES stream.
*/
public static class InvalidAESStreamException extends Exception
{
private static final long serialVersionUID = 1L;
public InvalidAESStreamException()
{
super();
};
public InvalidAESStreamException(Exception e)
{
super(e);
}
}
}
答案 0 :(得分:1)
这段代码将IV放在输出的中间位置:
byte[] encrypted = encrypt.update(input.getBytes());
output.append(HexUtils.toHex(encrypted));
encrypted = encrypt.doFinal();
if (encrypted != null)
{
// write authentication and AES initialization data
output.append(HexUtils.toHex(iv) + SPLITCHAR);
// data
output.append(HexUtils.toHex(encrypted));
}
要使用您的解密方法,它需要在开头。