Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.parquet.crypto;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import org.apache.parquet.bytes.BytesUtils;
import org.apache.parquet.format.BlockCipher;
import java.security.GeneralSecurityException;
public class AesGcmEncryptor extends AesCipher implements BlockCipher.Encryptor{
private long operationCounter;
AesGcmEncryptor(byte[] keyBytes) {
super(AesMode.GCM, keyBytes);
operationCounter = 0;
try {
cipher = Cipher.getInstance(AesMode.GCM.getCipherName());
} catch (GeneralSecurityException e) {
throw new ParquetCryptoRuntimeException("Failed to create GCM cipher", e);
}
}
@Override
public byte[] encrypt(byte[] plainText, byte[] AAD) {
return encrypt(true, plainText, AAD);
}
public byte[] encrypt(boolean writeLength, byte[] plainText, byte[] AAD) {
randomGenerator.nextBytes(localNonce);
return encrypt(writeLength, plainText, localNonce, AAD);
}
public byte[] encrypt(boolean writeLength, byte[] plainText, byte[] nonce, byte[] AAD) {
if (operationCounter > GCM_RANDOM_IV_SAME_KEY_MAX_OPS) {
throw new ParquetCryptoRuntimeException("Exceeded limit of AES GCM encryption operations with same key and random IV");
}
operationCounter++;
if (nonce.length != NONCE_LENGTH) {
throw new ParquetCryptoRuntimeException("Wrong nonce length " + nonce.length);
}
int plainTextLength = plainText.length;
int cipherTextLength = NONCE_LENGTH + plainTextLength + GCM_TAG_LENGTH;
int lengthBufferLength = writeLength? SIZE_LENGTH : 0;
byte[] cipherText = new byte[lengthBufferLength + cipherTextLength];
int inputLength = plainTextLength;
int inputOffset = 0;
int outputOffset = lengthBufferLength + NONCE_LENGTH;
try {
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH_BITS, nonce);
cipher.init(Cipher.ENCRYPT_MODE, aesKey, spec);
if (null != AAD) cipher.updateAAD(AAD);
cipher.doFinal(plainText, inputOffset, inputLength, cipherText, outputOffset);
} catch (GeneralSecurityException e) {
throw new ParquetCryptoRuntimeException("Failed to encrypt", e);
}
// Add ciphertext length
if (writeLength) {
System.arraycopy(BytesUtils.intToBytes(cipherTextLength), 0, cipherText, 0, lengthBufferLength);
}
// Add the nonce
System.arraycopy(nonce, 0, cipherText, lengthBufferLength, NONCE_LENGTH);
return cipherText;
}
}