为了在毕设中对图片进行加密处理,今天需要研究下AES。
为了加密,我们需要生成密钥,每个密码都有不同的用于密钥的格式,我们需要确保密钥的生成是随机的,这需要遵循下面的步骤:
1)为加密算法获取KeyGenerator。
2)用随机源来初始或密钥发生器。如果密码块的长度是可变的,还需要指定期望的密码块长度。
3)调用generateKey方法。
下面是生成AES密钥的方法:
public void generateKey() throws NoSuchAlgorithmException {
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom();
keygen.init(random);
this.key = keygen.generateKey();
}
static KeyGenerator getInstance(String algorithmName)
返回实现指定加密算法的 KeyGenerator 对象,如果未提供加密算法,则抛出一个NoSuchAlgorithmException异常。void init(SecureRandom random)
对密钥生成器进行初始化。
SecreKey generateKey()
生成一个新的密钥。
加密、解密:
如下所示,加密、解密都调用了相同的crypt方法,而crypt方法则调用密码的update和doFinal方法。
/**
* 加密
*/
public void encrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
this.crypt(in, out, Cipher.ENCRYPT_MODE);
}
/**
* 解密
*/
public void decrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
this.crypt(in, out, Cipher.DECRYPT_MODE);
}
/**
* 实际的加密解密过程
*/
public void crypt(InputStream in, OutputStream out, int mode) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(mode, this.key);
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
byte[] inBytes = new byte[blockSize];
byte[] outBytes = new byte[outputSize];
int inLength = 0;
boolean more = true;
while (more) {
inLength = in.read(inBytes);
if (inLength == blockSize) {
int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
out.write(outBytes, 0, outLength);
} else {
more = false;
}
}
if (inLength > 0)
outBytes = cipher.doFinal(inBytes, 0, inLength);
else
outBytes = cipher.doFinal();
out.write(outBytes);
out.flush();
}
完整代码:
public class AES {
private Key key;
/**
* 生成AES对称秘钥
*/
public void generateKey() throws NoSuchAlgorithmException {
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom();
keygen.init(random);
this.key = keygen.generateKey();
}
/**
* 加密
*/
public void encrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
this.crypt(in, out, Cipher.ENCRYPT_MODE);
}
/**
* 解密
*/
public void decrypt(InputStream in, OutputStream out) throws InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
this.crypt(in, out, Cipher.DECRYPT_MODE);
}
/**
* 实际的加密解密过程
*/
public void crypt(InputStream in, OutputStream out, int mode) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(mode, this.key);
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
byte[] inBytes = new byte[blockSize];
byte[] outBytes = new byte[outputSize];
int inLength = 0;
boolean more = true;
while (more) {
inLength = in.read(inBytes);
if (inLength == blockSize) { //只要输入数据块具有全长度(长度可被8整除),调用update方法
int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
out.write(outBytes, 0, outLength);
} else {
more = false;
}
}
if (inLength > 0) //不具有全长度,调用doFinal方法
outBytes = cipher.doFinal(inBytes, 0, inLength);
else
outBytes = cipher.doFinal();
out.write(outBytes);
out.flush();
}
public void setKey(Key key) {
this.key = key;
}
public Key getKey() {
return key;
}
}