use of com.github.zhenwei.core.crypto.InvalidCipherTextException in project LinLong-Java by zhenwei1108.
the class DESedeWrapEngine method unwrap.
/**
* Method unwrap
*
* @param in byte array containing the wrapped key.
* @param inOff off set into in that the data starts at.
* @param inLen length of the data.
* @return the unwrapped bytes.
* @throws InvalidCipherTextException
*/
public byte[] unwrap(byte[] in, int inOff, int inLen) throws InvalidCipherTextException {
if (forWrapping) {
throw new IllegalStateException("Not set for unwrapping");
}
if (in == null) {
throw new InvalidCipherTextException("Null pointer as ciphertext");
}
final int blockSize = engine.getBlockSize();
if (inLen % blockSize != 0) {
throw new InvalidCipherTextException("Ciphertext not multiple of " + blockSize);
}
/*
// Check if the length of the cipher text is reasonable given the key
// type. It must be 40 bytes for a 168 bit key and either 32, 40, or
// 48 bytes for a 128, 192, or 256 bit key. If the length is not supported
// or inconsistent with the algorithm for which the key is intended,
// return error.
//
// we do not accept 168 bit keys. it has to be 192 bit.
int lengthA = (estimatedKeyLengthInBit / 8) + 16;
int lengthB = estimatedKeyLengthInBit % 8;
if ((lengthA != keyToBeUnwrapped.length) || (lengthB != 0)) {
throw new XMLSecurityException("empty");
}
*/
// Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK
// and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3.
ParametersWithIV param2 = new ParametersWithIV(this.param, IV2);
this.engine.init(false, param2);
byte[] TEMP3 = new byte[inLen];
for (int currentBytePos = 0; currentBytePos != inLen; currentBytePos += blockSize) {
engine.processBlock(in, inOff + currentBytePos, TEMP3, currentBytePos);
}
// Reverse the order of the octets in TEMP3 and call the result TEMP2.
byte[] TEMP2 = reverse(TEMP3);
// Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets.
this.iv = new byte[8];
byte[] TEMP1 = new byte[TEMP2.length - 8];
System.arraycopy(TEMP2, 0, this.iv, 0, 8);
System.arraycopy(TEMP2, 8, TEMP1, 0, TEMP2.length - 8);
// Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV
// found in the previous step. Call the result WKCKS.
this.paramPlusIV = new ParametersWithIV(this.param, this.iv);
this.engine.init(false, this.paramPlusIV);
byte[] WKCKS = new byte[TEMP1.length];
for (int currentBytePos = 0; currentBytePos != WKCKS.length; currentBytePos += blockSize) {
engine.processBlock(TEMP1, currentBytePos, WKCKS, currentBytePos);
}
// Decompose WKCKS. CKS is the last 8 octets and WK, the wrapped key, are
// those octets before the CKS.
byte[] result = new byte[WKCKS.length - 8];
byte[] CKStoBeVerified = new byte[8];
System.arraycopy(WKCKS, 0, result, 0, WKCKS.length - 8);
System.arraycopy(WKCKS, WKCKS.length - 8, CKStoBeVerified, 0, 8);
// with the CKS extracted in the above step. If they are not equal, return error.
if (!checkCMSKeyChecksum(result, CKStoBeVerified)) {
throw new InvalidCipherTextException("Checksum inside ciphertext is corrupted");
}
// WK is the wrapped key, now extracted for use in data decryption.
return result;
}
use of com.github.zhenwei.core.crypto.InvalidCipherTextException in project LinLong-Java by zhenwei1108.
the class EthereumIESEngine method processBlock.
public byte[] processBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException {
if (forEncryption) {
if (keyPairGenerator != null) {
EphemeralKeyPair ephKeyPair = keyPairGenerator.generate();
this.privParam = ephKeyPair.getKeyPair().getPrivate();
this.V = ephKeyPair.getEncodedPublicKey();
}
} else {
if (keyParser != null) {
ByteArrayInputStream bIn = new ByteArrayInputStream(in, inOff, inLen);
try {
this.pubParam = keyParser.readKey(bIn);
} catch (IOException e) {
throw new InvalidCipherTextException("unable to recover ephemeral public key: " + e.getMessage(), e);
} catch (IllegalArgumentException e) {
throw new InvalidCipherTextException("unable to recover ephemeral public key: " + e.getMessage(), e);
}
int encLength = (inLen - bIn.available());
this.V = Arrays.copyOfRange(in, inOff, inOff + encLength);
}
}
// Compute the common value and convert to byte array.
agree.init(privParam);
BigInteger z = agree.calculateAgreement(pubParam);
byte[] Z = BigIntegers.asUnsignedByteArray(agree.getFieldSize(), z);
// Create input to KDF.
if (V.length != 0) {
byte[] VZ = Arrays.concatenate(V, Z);
Arrays.fill(Z, (byte) 0);
Z = VZ;
}
try {
// Initialise the KDF.
KDFParameters kdfParam = new KDFParameters(Z, param.getDerivationV());
kdf.init(kdfParam);
return forEncryption ? encryptBlock(in, inOff, inLen) : decryptBlock(in, inOff, inLen);
} finally {
Arrays.fill(Z, (byte) 0);
}
}
use of com.github.zhenwei.core.crypto.InvalidCipherTextException in project LinLong-Java by zhenwei1108.
the class NaccacheSternEngine method processBlock.
/**
* Process a single Block using the Naccache-Stern algorithm.
*
* @see com.github.zhenwei.core.crypto.AsymmetricBlockCipher#processBlock(byte[], int, int)
*/
public byte[] processBlock(byte[] in, int inOff, int len) throws InvalidCipherTextException {
if (key == null) {
throw new IllegalStateException("NaccacheStern engine not initialised");
}
if (len > (getInputBlockSize() + 1)) {
throw new DataLengthException("input too large for Naccache-Stern cipher.\n");
}
if (!forEncryption) {
// At decryption make sure that we receive padded data blocks
if (len < getInputBlockSize()) {
throw new InvalidCipherTextException("BlockLength does not match modulus for Naccache-Stern cipher.\n");
}
}
byte[] block;
if (inOff != 0 || len != in.length) {
block = new byte[len];
System.arraycopy(in, inOff, block, 0, len);
} else {
block = in;
}
// transform input into BigInteger
BigInteger input = new BigInteger(1, block);
if (debug) {
System.out.println("input as BigInteger: " + input);
}
byte[] output;
if (forEncryption) {
output = encrypt(input);
} else {
Vector plain = new Vector();
NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters) key;
Vector primes = priv.getSmallPrimes();
// Get Chinese Remainders of CipherText
for (int i = 0; i < primes.size(); i++) {
BigInteger exp = input.modPow(priv.getPhi_n().divide((BigInteger) primes.elementAt(i)), priv.getModulus());
Vector al = lookup[i];
if (lookup[i].size() != ((BigInteger) primes.elementAt(i)).intValue()) {
if (debug) {
System.out.println("Prime is " + primes.elementAt(i) + ", lookup table has size " + al.size());
}
throw new InvalidCipherTextException("Error in lookup Array for " + ((BigInteger) primes.elementAt(i)).intValue() + ": Size mismatch. Expected ArrayList with length " + ((BigInteger) primes.elementAt(i)).intValue() + " but found ArrayList of length " + lookup[i].size());
}
int lookedup = al.indexOf(exp);
if (lookedup == -1) {
if (debug) {
System.out.println("Actual prime is " + primes.elementAt(i));
System.out.println("Decrypted value is " + exp);
System.out.println("LookupList for " + primes.elementAt(i) + " with size " + lookup[i].size() + " is: ");
for (int j = 0; j < lookup[i].size(); j++) {
System.out.println(lookup[i].elementAt(j));
}
}
throw new InvalidCipherTextException("Lookup failed");
}
plain.addElement(BigInteger.valueOf(lookedup));
}
BigInteger test = chineseRemainder(plain, primes);
// Should not be used as an oracle, so reencrypt output to see
// if it corresponds to input
// this breaks probabilisic encryption, so disable it. Anyway, we do
// use the first n primes for key generation, so it is pretty easy
// to guess them. But as stated in the paper, this is not a security
// breach. So we can just work with the correct sigma.
// if (debug) {
// System.out.println("Decryption is " + test);
// }
// if ((key.getG().modPow(test, key.getModulus())).equals(input)) {
// output = test.toByteArray();
// } else {
// if(debug){
// System.out.println("Engine seems to be used as an oracle,
// returning null");
// }
// output = null;
// }
output = test.toByteArray();
}
return output;
}
use of com.github.zhenwei.core.crypto.InvalidCipherTextException in project LinLong-Java by zhenwei1108.
the class ISO9796d1Encoding method decodeBlock.
/**
* @throws InvalidCipherTextException if the decrypted block is not a valid ISO 9796 bit string
*/
private byte[] decodeBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException {
byte[] block = engine.processBlock(in, inOff, inLen);
int r = 1;
int t = (bitSize + 13) / 16;
BigInteger iS = new BigInteger(1, block);
BigInteger iR;
if (iS.mod(SIXTEEN).equals(SIX)) {
iR = iS;
} else if ((modulus.subtract(iS)).mod(SIXTEEN).equals(SIX)) {
iR = modulus.subtract(iS);
} else {
throw new InvalidCipherTextException("resulting integer iS or (modulus - iS) is not congruent to 6 mod 16");
}
block = convertOutputDecryptOnly(iR);
if ((block[block.length - 1] & 0x0f) != 0x6) {
throw new InvalidCipherTextException("invalid forcing byte in block");
}
block[block.length - 1] = (byte) (((block[block.length - 1] & 0xff) >>> 4) | ((inverse[(block[block.length - 2] & 0xff) >> 4]) << 4));
block[0] = (byte) ((shadows[(block[1] & 0xff) >>> 4] << 4) | shadows[block[1] & 0x0f]);
boolean boundaryFound = false;
int boundary = 0;
for (int i = block.length - 1; i >= block.length - 2 * t; i -= 2) {
int val = ((shadows[(block[i] & 0xff) >>> 4] << 4) | shadows[block[i] & 0x0f]);
if (((block[i - 1] ^ val) & 0xff) != 0) {
if (!boundaryFound) {
boundaryFound = true;
r = (block[i - 1] ^ val) & 0xff;
boundary = i - 1;
} else {
throw new InvalidCipherTextException("invalid tsums in block");
}
}
}
block[boundary] = 0;
byte[] nblock = new byte[(block.length - boundary) / 2];
for (int i = 0; i < nblock.length; i++) {
nblock[i] = block[2 * i + boundary + 1];
}
padBits = r - 1;
return nblock;
}
use of com.github.zhenwei.core.crypto.InvalidCipherTextException in project LinLong-Java by zhenwei1108.
the class CCMBlockCipher method processPacket.
/**
* Process a packet of data for either CCM decryption or encryption.
*
* @param in data for processing.
* @param inOff offset at which data starts in the input array.
* @param inLen length of the data in the input array.
* @param output output array.
* @param outOff offset into output array to start putting processed bytes.
* @return the number of bytes added to output.
* @throws IllegalStateException if the cipher is not appropriately set up.
* @throws InvalidCipherTextException if the input data is truncated or the mac check fails.
* @throws DataLengthException if output buffer too short.
*/
public int processPacket(byte[] in, int inOff, int inLen, byte[] output, int outOff) throws IllegalStateException, InvalidCipherTextException, DataLengthException {
// Need to keep the CTR and CBC Mac parts around and reset
if (keyParam == null) {
throw new IllegalStateException("CCM cipher unitialized.");
}
int n = nonce.length;
int q = 15 - n;
if (q < 4) {
int limitLen = 1 << (8 * q);
if (inLen >= limitLen) {
throw new IllegalStateException("CCM packet too large for choice of q.");
}
}
byte[] iv = new byte[blockSize];
iv[0] = (byte) ((q - 1) & 0x7);
System.arraycopy(nonce, 0, iv, 1, nonce.length);
BlockCipher ctrCipher = new SICBlockCipher(cipher);
ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
int outputLen;
int inIndex = inOff;
int outIndex = outOff;
if (forEncryption) {
outputLen = inLen + macSize;
if (output.length < (outputLen + outOff)) {
throw new OutputLengthException("Output buffer too short.");
}
calculateMac(in, inOff, inLen, macBlock);
byte[] encMac = new byte[blockSize];
// S0
ctrCipher.processBlock(macBlock, 0, encMac, 0);
while (// S1...
inIndex < (inOff + inLen - blockSize)) {
ctrCipher.processBlock(in, inIndex, output, outIndex);
outIndex += blockSize;
inIndex += blockSize;
}
byte[] block = new byte[blockSize];
System.arraycopy(in, inIndex, block, 0, inLen + inOff - inIndex);
ctrCipher.processBlock(block, 0, block, 0);
System.arraycopy(block, 0, output, outIndex, inLen + inOff - inIndex);
System.arraycopy(encMac, 0, output, outOff + inLen, macSize);
} else {
if (inLen < macSize) {
throw new InvalidCipherTextException("data too short");
}
outputLen = inLen - macSize;
if (output.length < (outputLen + outOff)) {
throw new OutputLengthException("Output buffer too short.");
}
System.arraycopy(in, inOff + outputLen, macBlock, 0, macSize);
ctrCipher.processBlock(macBlock, 0, macBlock, 0);
for (int i = macSize; i != macBlock.length; i++) {
macBlock[i] = 0;
}
while (inIndex < (inOff + outputLen - blockSize)) {
ctrCipher.processBlock(in, inIndex, output, outIndex);
outIndex += blockSize;
inIndex += blockSize;
}
byte[] block = new byte[blockSize];
System.arraycopy(in, inIndex, block, 0, outputLen - (inIndex - inOff));
ctrCipher.processBlock(block, 0, block, 0);
System.arraycopy(block, 0, output, outIndex, outputLen - (inIndex - inOff));
byte[] calculatedMacBlock = new byte[blockSize];
calculateMac(output, outOff, outputLen, calculatedMacBlock);
if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock)) {
throw new InvalidCipherTextException("mac check in CCM failed");
}
}
return outputLen;
}
Aggregations