下面列出了怎么用org.bouncycastle.crypto.params.AEADParameters的API类实例代码及写法,或者点击链接到github查看源代码。
public static byte[] decrypt(byte[] key, byte[] data) {
// TODO utilize GCMAES#decrypt method
try {
if (data.length < NONCE_LENGTH + TAG_LENGTH) {
throw new IllegalArgumentException("data packet too short");
}
int cipherTextLength = data.length - NONCE_LENGTH - TAG_LENGTH;
byte[] nonce = Arrays.copyOf(data, NONCE_LENGTH);
GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
AEADParameters parameters = new AEADParameters(new KeyParameter(key), TAG_LENGTH * 8, nonce);
cipher.init(false, parameters);
byte[] out = new byte[cipher.getOutputSize(cipherTextLength + TAG_LENGTH)];
int pos = cipher.processBytes(data, NONCE_LENGTH, data.length - NONCE_LENGTH, out, 0);
pos += cipher.doFinal(out, pos);
return Arrays.copyOf(out, pos);
} catch (IllegalStateException | InvalidCipherTextException ex) {
throw new IllegalArgumentException(ex);
}
}
/**
* Decrypt the byte array.
*
* @param encryptedByteArray cipher text
*/
@Override
public byte[] decrypt(byte[] encryptedByteArray) {
if (encryptedByteArray.length <= this.ivGenerator.getKeyLength()) {
throw new IllegalCipherTextSizeException();
}
byte[] iv = subArray(encryptedByteArray, 0, this.ivGenerator.getKeyLength());
encryptedByteArray = subArray(encryptedByteArray, this.ivGenerator.getKeyLength(),
encryptedByteArray.length);
GCMBlockCipher blockCipher = new GCMBlockCipher(new AESEngine());
blockCipher.init(false, new AEADParameters(secretKey, 128, iv, null));
return process(blockCipher, encryptedByteArray);
}
public SAES256v01(byte[] secretBytes, byte[] salt) {
this.salt = salt.clone();
secretBytes = secretBytes.clone();
if (secretBytes.length != KEY_SIZE_BYTES) {
secretBytes = Hashing.sha256().hashBytes(secretBytes).asBytes();
}
try {
KeyParameter key = new KeyParameter(secretBytes);
AEADParameters params = new AEADParameters(key, MAC_SIZE_BITS, this.salt);
this.encryptor = new GCMBlockCipher(new AESFastEngine());
this.encryptor.init(true, params);
this.decryptor = new GCMBlockCipher(new AESFastEngine());
this.decryptor.init(false, params);
} catch (Exception e) {
throw new RuntimeException("could not create cipher for AES256", e);
} finally {
Arrays.fill(secretBytes, (byte) 0);
}
}
public CipherWriteStreamValidation(byte[] secretBytes, byte[] salt) {
this.salt = salt.clone();
secretBytes = secretBytes.clone();
if (secretBytes.length != KEY_SIZE_BYTES) {
secretBytes = Hashing.sha256().hashBytes(secretBytes).asBytes();
}
try {
KeyParameter key = new KeyParameter(secretBytes);
AEADParameters params = new AEADParameters(key, MAC_SIZE_BITS, this.salt);
this.encryptor = new GCMBlockCipher(new AESFastEngine());
this.encryptor.init(true, params);
this.decryptor = new GCMBlockCipher(new AESFastEngine());
this.decryptor.init(false, params);
} catch (Exception e) {
throw new RuntimeException("could not create cipher for AES256", e);
} finally {
Arrays.fill(secretBytes, (byte) 0);
}
}
/**
* Encrypt the byte array.
*
* @param byteArray plain text
*/
@Override
public byte[] encrypt(byte[] byteArray) {
byte[] iv = this.ivGenerator.generateKey();
GCMBlockCipher blockCipher = new GCMBlockCipher(new AESEngine());
blockCipher.init(true, new AEADParameters(secretKey, 128, iv, null));
byte[] encrypted = process(blockCipher, byteArray);
return iv != null ? concatenate(iv, encrypted) : encrypted;
}
public byte[] decrypt(PacketHeader header, ByteBuffer buffer, int dataLen)
throws InvalidCipherTextException {
Pair<byte[], byte[]> parameters = computeParameters(header);
byte[] headerWithoutMac = new byte[header.getSize() - MAC_LEN];
System.arraycopy(buffer.array(), MAC_LEN, headerWithoutMac, 0, headerWithoutMac.length);
// Get the header without a MAC for the associated text field
CipherParameters cipherParameters = new AEADParameters(
new KeyParameter(parameters.getKey()),
8 * MAC_LEN,
parameters.getValue(),
headerWithoutMac
);
byte[] result;
int len;
synchronized (cipher) {
cipher.init(false, cipherParameters);
result = new byte[cipher.getOutputSize(dataLen + MAC_LEN)];
len = cipher.processBytes(buffer.array(), header.getSize(), dataLen, result, 0);
len += cipher.processBytes(buffer.array(), 0, MAC_LEN, result, len);
len += cipher.doFinal(result, len);
if (len != dataLen)
throw new IllegalArgumentException(len + " != " + dataLen);
}
return result;
}
protected CipherParameters getCipherParameters(boolean forEncryption) {
// logger.debug("getCipherParameters subkey:{}",Arrays.toString(forEncryption ? encSubkey : decSubkey));
byte[] nonce;
if (!isForUdp) {
nonce = forEncryption ? Arrays.copyOf(encNonce, getNonceLength()) : Arrays.copyOf(decNonce, getNonceLength());
} else {
nonce = ZERO_NONCE;
}
return new AEADParameters(
new KeyParameter(forEncryption ? encSubkey : decSubkey),
getTagLength() * 8,
nonce
);
}
public static InputStream setupInputStream(InputStream is, byte[] keyAndIv) {
if (keyAndIv != null && keyAndIv.length == 48) {
byte[] key = new byte[32];
byte[] iv = new byte[16];
System.arraycopy(keyAndIv, 0, iv, 0, 16);
System.arraycopy(keyAndIv, 16, key, 0, 32);
AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
cipher.init(true, new AEADParameters(new KeyParameter(key), 128, iv));
return new CipherInputStream(is, cipher);
} else {
return is;
}
}
public static OutputStream setupOutputStream(OutputStream os, String reference) {
if (reference != null && reference.length() == 96) {
byte[] keyAndIv = hexToBytes(reference);
byte[] key = new byte[32];
byte[] iv = new byte[16];
System.arraycopy(keyAndIv, 0, iv, 0, 16);
System.arraycopy(keyAndIv, 16, key, 0, 32);
AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
cipher.init(false, new AEADParameters(new KeyParameter(key), 128, iv));
return new CipherOutputStream(os, cipher);
} else {
return os;
}
}
public static InputStream upgrade(DownloadableFile file, InputStream is) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, NoSuchProviderException {
if (file.getKey() != null && file.getIv() != null) {
AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
cipher.init(true, new AEADParameters(new KeyParameter(file.getKey()), 128, file.getIv()));
return new CipherInputStream(is, cipher);
} else {
return is;
}
}
/**
* Returns decrypted data.
*
* @param key
* @param nonce nonce/ IV
* @param header
* @param encryptedData
* @param tag
* @param optional optional AADBytes (post header)
* @return decrypted data
* @throws IllegalArgumentException on decryption exceptions
* @throws NullPointerException on null arguments
*/
public static byte[] decrypt(
byte[] key,
byte[] nonce,
byte[] header,
byte[] encryptedData,
byte[] tag,
Optional<byte[]> optional) {
try {
GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
AEADParameters parameters = new AEADParameters(new KeyParameter(key), tag.length * 8, nonce, header);
cipher.init(false, parameters);
if (optional.isPresent()) {
byte[] aadBytes = optional.get();
cipher.processAADBytes(aadBytes, 0, aadBytes.length);
}
byte[] out = new byte[cipher.getOutputSize(encryptedData.length + tag.length)];
int pos = cipher.processBytes(encryptedData, 0, encryptedData.length, out, 0);
pos += cipher.processBytes(tag, 0, tag.length, out, pos);
pos += cipher.doFinal(out, pos);
return Arrays.copyOf(out, pos);
} catch (IllegalStateException | InvalidCipherTextException | RuntimeCryptoException ex) {
throw new IllegalStateException("GCM decrypt error", ex);
}
}
public CipherOutputStream newCipherOutputStream(OutputStream os, byte[] password) throws IOException {
byte[] salt = randomBytes(saltLength);
byte[] nonce = randomBytes(nonceLength);
os.write(salt);
os.write(nonce);
byte[] dk = kdf.apply(password, salt);
GCMBlockCipher cipher = new GCMBlockCipher(new AESEngine());
AEADParameters parameters = new AEADParameters(new KeyParameter(dk), tagLength * 8, nonce);
cipher.init(true, parameters);
return new CipherOutputStream(os, cipher);
}
public CipherInputStream newCipherInputStream(InputStream is, byte[] password) throws IOException {
byte[] salt = IOUtils.readFully(is, saltLength);
byte[] nonce = IOUtils.readFully(is, nonceLength);
byte[] dk = kdf.apply(password, salt);
GCMBlockCipher cipher = new GCMBlockCipher(new AESEngine());
AEADParameters parameters = new AEADParameters(new KeyParameter(dk), tagLength * 8, nonce);
cipher.init(false, parameters);
return new CipherInputStream(is, cipher);
}
public static InputStream upgrade(DownloadableFile file, InputStream is) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, NoSuchProviderException {
if (file.getKey() != null && file.getIv() != null) {
AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
cipher.init(true, new AEADParameters(new KeyParameter(file.getKey()), 128, file.getIv()));
return new CipherInputStream(is, cipher);
} else {
return is;
}
}
@Override
public byte[] encrypt(byte[] data, byte[] randomKeyBytes) throws IOException, InvalidKeyException,
InvalidAlgorithmParameterException, InvalidCipherTextException {
AEADBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
cipher.init(true, new AEADParameters(new KeyParameter(randomKeyBytes), 128, randomIvBytes));
return cipherData(cipher, data);
}
@Override
public byte[] decrypt(byte[] data, byte[] randomKey)
throws InvalidKeyException, InvalidAlgorithmParameterException, IOException,
IllegalStateException, InvalidCipherTextException {
AEADBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
cipher.init(false, new AEADParameters(new KeyParameter(randomKey), 128, randomIvBytes));
return cipherData(cipher, data);
}
public ByteBuffer encrypt(Packet packet) {
Pair<byte[], byte[]> parameters = computeParameters(packet.getHeader());
// Write header (this is temporary)
ByteBuffer headerBuffer = packet.writeHeader(
ByteBuffer
.allocate(packet.getHeader().getSize())
.order(ByteOrder.BIG_ENDIAN)
);
// Get the header without a MAC for the associated text field
byte[] headerWithoutMac = new byte[packet.getHeader().getSize() - MAC_LEN];
System.arraycopy(headerBuffer.array(), MAC_LEN, headerWithoutMac, 0, headerWithoutMac.length);
CipherParameters cipherParameters = new AEADParameters(
new KeyParameter(parameters.getKey()),
8 * MAC_LEN,
parameters.getValue(),
headerWithoutMac
);
int dataLen = packet.getBody().getSize();
ByteBuffer packetBuffer = packet.writeBody(ByteBuffer.allocate(dataLen).order(ByteOrder.BIG_ENDIAN));
byte[] result;
int len;
synchronized (cipher) {
cipher.init(true, cipherParameters);
result = new byte[cipher.getOutputSize(dataLen)];
len = cipher.processBytes(packetBuffer.array(), 0, dataLen, result, 0);
try {
len += cipher.doFinal(result, len);
} catch (InvalidCipherTextException e) {
throw new RuntimeException(e);
}
}
ByteBuffer outputBuffer = ByteBuffer.allocate(MAC_LEN + headerWithoutMac.length + (len - MAC_LEN));
// Copy the mac to the packet header
System.arraycopy(result, len - MAC_LEN, packet.getHeader().getMac(), 0, MAC_LEN);
// MAC
outputBuffer.put(result, len - MAC_LEN, MAC_LEN);
// Rest of header
outputBuffer.put(headerWithoutMac);
// Encrypted body
outputBuffer.put(result, 0, len - MAC_LEN);
return outputBuffer;
}
private static AEADBlockCipher createOCBCipher(boolean forEncryption, AEADParameters parameters) {
AEADBlockCipher c = new OCBBlockCipher(new AESEngine(), new AESEngine());
c.init(forEncryption, parameters);
return c;
}