Skip to content
Permalink
Browse files
Cipher.getInstance throw GeneralSecurityException
This closes #43
  • Loading branch information
dianfu authored and winningsix committed Jan 15, 2016
1 parent 32e6727 commit 57f697939d549bfec952417e51a8f3be6048a55d
Show file tree
Hide file tree
Showing 12 changed files with 232 additions and 187 deletions.
@@ -72,8 +72,8 @@ More detailed information about the configurations are as follows.
| chimera.crypto.cipher.transformation | AES/CTR/NoPadding | The value is identical to the transformations described in the Cipher section of the Java Cryptography Architecture Standard Algorithm Name Documentation. Currently only "AES/CTR/NoPadding" algorithm is supported.|
| chimera.crypto.cipher.classes | com.intel.chimera.crypto.OpensslCipher, com.intel.chimera.crypto.JceCipher | Comma-separated list of cipher classes which implement cipher algorithm of "AES/CTR/NoPadding". A cipher implementation encapsulates the encryption and decryption details. The first available implementation appearing in this list will be used. |

## Building from the source code
Building from the source code is an option when your OS platform and CPU architecture is not supported. To build chimera, you need Git, JDK (1.6 or higher), g++ compiler (mingw in Windows) etc.
## Building from the source code
Building from the source code is an option when your OS platform and CPU architecture is not supported. To build Chimera, you need JDK 1.7 or higher, OpenSSL 1.0.1c or higher, etc.

$ git clone https://github.com/intel-hadoop/chimera.git
$ cd chimera
15 pom.xml
@@ -34,13 +34,15 @@
<maven-gpg-plugin.version>1.6</maven-gpg-plugin.version>
<maven-javadoc-plugin.version>2.8.1</maven-javadoc-plugin.version>
<maven-source-plugin.version>2.3</maven-source-plugin.version>
<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
<findbugs-maven-plugin.version>3.0.2</findbugs-maven-plugin.version>
<apache-rat-plugin.version>0.11</apache-rat-plugin.version>
<nexus-staging-maven-plugin.version>1.6.3</nexus-staging-maven-plugin.version>
<junit.version>4.8.2</junit.version>
<guava.version>11.0.2</guava.version>
<commons-logging.version>1.1.3</commons-logging.version>
<slf4j-api.version>1.7.10</slf4j-api.version>
<javac.version>1.7</javac.version>
</properties>

<profiles>
@@ -276,6 +278,15 @@
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>${nexus-staging-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${javac.version}</source>
<target>${javac.version}</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
@@ -317,6 +328,10 @@
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>

@@ -21,11 +21,16 @@
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.util.Properties;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.ShortBufferException;

import com.google.common.base.Preconditions;
import com.intel.chimera.crypto.Cipher;
import com.intel.chimera.crypto.CipherFactory;
import com.intel.chimera.input.ChannelInput;
import com.intel.chimera.input.Input;
import com.intel.chimera.input.StreamInput;
@@ -80,12 +85,12 @@ public class CryptoInputStream extends InputStream implements

public CryptoInputStream(Properties props, InputStream in,
byte[] key, byte[] iv) throws IOException {
this(in, CipherFactory.getInstance(props), Utils.getBufferSize(props), key, iv);
this(in, Utils.getCipherInstance(props), Utils.getBufferSize(props), key, iv);
}

public CryptoInputStream(Properties props, ReadableByteChannel in,
byte[] key, byte[] iv) throws IOException {
this(in, CipherFactory.getInstance(props), Utils.getBufferSize(props), key, iv);
this(in, Utils.getCipherInstance(props), Utils.getBufferSize(props), key, iv);
}

public CryptoInputStream(InputStream in, Cipher cipher,
@@ -427,7 +432,11 @@ protected void resetCipher(long position)
throws IOException {
final long counter = getCounter(position);
Utils.calculateIV(initIV, counter, iv);
cipher.init(Cipher.DECRYPT_MODE, key, iv);
try {
cipher.init(Cipher.DECRYPT_MODE, key, iv);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IOException(e);
}
cipherReset = false;
}

@@ -448,15 +457,20 @@ protected void resetStreamOffset(long offset) throws IOException {
protected void decryptBuffer(ByteBuffer out)
throws IOException {
int inputSize = inBuffer.remaining();
int n = cipher.update(inBuffer, out);
if (n < inputSize) {
/**
* Typically code will not get here. Cipher#update will consume all
* input data and put result in outBuffer.
* Cipher#doFinal will reset the cipher context.
*/
cipher.doFinal(inBuffer, outBuffer);
cipherReset = true;
try {
int n = cipher.update(inBuffer, out);
if (n < inputSize) {
/**
* Typically code will not get here. Cipher#update will consume all
* input data and put result in outBuffer.
* Cipher#doFinal will reset the cipher context.
*/
cipher.doFinal(inBuffer, outBuffer);
cipherReset = true;
}
} catch (ShortBufferException | IllegalBlockSizeException
| BadPaddingException e) {
throw new IOException(e);
}
}

@@ -21,11 +21,16 @@
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.WritableByteChannel;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.util.Properties;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.ShortBufferException;

import com.google.common.base.Preconditions;
import com.intel.chimera.crypto.Cipher;
import com.intel.chimera.crypto.CipherFactory;
import com.intel.chimera.output.ChannelOutput;
import com.intel.chimera.output.Output;
import com.intel.chimera.output.StreamOutput;
@@ -79,12 +84,12 @@ public class CryptoOutputStream extends OutputStream implements

public CryptoOutputStream(Properties props, OutputStream out,
byte[] key, byte[] iv) throws IOException {
this(out, CipherFactory.getInstance(props), Utils.getBufferSize(props), key, iv);
this(out, Utils.getCipherInstance(props), Utils.getBufferSize(props), key, iv);
}

public CryptoOutputStream(Properties props, WritableByteChannel out,
byte[] key, byte[] iv) throws IOException {
this(out, CipherFactory.getInstance(props), Utils.getBufferSize(props), key, iv);
this(out, Utils.getCipherInstance(props), Utils.getBufferSize(props), key, iv);
}

public CryptoOutputStream(OutputStream out, Cipher cipher,
@@ -271,22 +276,31 @@ private void resetCipher() throws IOException {
inBuffer.position(padding); // Set proper position for input data.

Utils.calculateIV(initIV, counter, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
try {
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IOException(e);
}
cipherReset = false;
}

private void encryptBuffer(ByteBuffer out)
throws IOException {
int inputSize = inBuffer.remaining();
int n = cipher.update(inBuffer, out);
if (n < inputSize) {
/**
* Typically code will not get here. Cipher#update will consume all
* input data and put result in outBuffer.
* Cipher#doFinal will reset the cipher context.
*/
cipher.doFinal(inBuffer, outBuffer);
cipherReset = true;
try {
int n = cipher.update(inBuffer, out);
if (n < inputSize) {
/**
* Typically code will not get here. Cipher#update will consume all
* input data and put result in outBuffer.
* Cipher#doFinal will reset the cipher context.
*/
cipher.doFinal(inBuffer, outBuffer);
cipherReset = true;
}
} catch (ShortBufferException | BadPaddingException
| IllegalBlockSizeException e) {
throw new IOException(e);
}
}

@@ -21,10 +21,17 @@
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.ShortBufferException;

import com.google.common.base.Preconditions;
import com.intel.chimera.crypto.Cipher;
import com.intel.chimera.crypto.CipherFactory;
@@ -50,12 +57,12 @@ public class PositionedCryptoInputStream extends CryptoInputStream {

public PositionedCryptoInputStream(Properties props, InputStream in,
byte[] key, byte[] iv, long streamOffset) throws IOException {
this(in, CipherFactory.getInstance(props), Utils.getBufferSize(props), key, iv, streamOffset);
this(in, Utils.getCipherInstance(props), Utils.getBufferSize(props), key, iv, streamOffset);
}

public PositionedCryptoInputStream(Properties props, ReadableByteChannel in,
byte[] key, byte[] iv, long streamOffset) throws IOException {
this(in, CipherFactory.getInstance(props), Utils.getBufferSize(props), key, iv, streamOffset);
this(in, Utils.getCipherInstance(props), Utils.getBufferSize(props), key, iv, streamOffset);
}

public PositionedCryptoInputStream(InputStream in, Cipher cipher,
@@ -76,7 +83,7 @@ public PositionedCryptoInputStream(
byte[] iv,
long streamOffset) throws IOException {
super(input, cipher, bufferSize, key, iv, streamOffset);
Utils.checkPositionedStreamCipher(cipher);
Utils.checkStreamCipher(cipher);
}

protected long getPos() throws IOException {
@@ -148,15 +155,20 @@ private void decrypt(CipherState state, ByteBuffer inBuffer,
private void decryptBuffer(CipherState state, ByteBuffer inBuffer, ByteBuffer outBuffer)
throws IOException {
int inputSize = inBuffer.remaining();
int n = state.getCipher().update(inBuffer, outBuffer);
if (n < inputSize) {
/**
* Typically code will not get here. Cipher#update will consume all
* input data and put result in outBuffer.
* Cipher#doFinal will reset the cipher context.
*/
state.getCipher().doFinal(inBuffer, outBuffer);
state.reset(true);
try {
int n = state.getCipher().update(inBuffer, outBuffer);
if (n < inputSize) {
/**
* Typically code will not get here. Cipher#update will consume all
* input data and put result in outBuffer.
* Cipher#doFinal will reset the cipher context.
*/
state.getCipher().doFinal(inBuffer, outBuffer);
state.reset(true);
}
} catch (ShortBufferException | IllegalBlockSizeException
| BadPaddingException e) {
throw new IOException(e);
}
}

@@ -186,16 +198,25 @@ private void resetCipher(CipherState state, long position, byte[] iv)
throws IOException {
final long counter = getCounter(position);
Utils.calculateIV(getInitIV(), counter, iv);
state.getCipher().init(Cipher.DECRYPT_MODE, getKey(), iv);
try {
state.getCipher().init(Cipher.DECRYPT_MODE, getKey(), iv);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IOException(e);
}
state.reset(false);
}

/** Get Cipher from pool */
private CipherState getCipherState() throws IOException {
CipherState state = cipherPool.poll();
if (state == null) {
Cipher cipher = CipherFactory.getInstance(getCipher().getProperties(),
getCipher().getTransformation());
Cipher cipher;
try {
cipher = CipherFactory.getInstance(getCipher().getProperties(),
getCipher().getTransformation());
} catch (GeneralSecurityException e) {
throw new IOException(e);
}
state = new CipherState(cipher);
}

@@ -23,7 +23,6 @@
import java.util.Properties;

import com.intel.chimera.crypto.Cipher;
import com.intel.chimera.crypto.CipherFactory;
import com.intel.chimera.output.ChannelOutput;
import com.intel.chimera.output.Output;
import com.intel.chimera.output.StreamOutput;
@@ -37,12 +36,12 @@
public class PositionedCryptoOutputStream extends CryptoOutputStream {
public PositionedCryptoOutputStream(Properties props, OutputStream out,
byte[] key, byte[] iv, long streamOffset) throws IOException {
this(out, CipherFactory.getInstance(props), Utils.getBufferSize(props), key, iv, streamOffset);
this(out, Utils.getCipherInstance(props), Utils.getBufferSize(props), key, iv, streamOffset);
}

public PositionedCryptoOutputStream(Properties props, WritableByteChannel out,
byte[] key, byte[] iv, long streamOffset) throws IOException {
this(out, CipherFactory.getInstance(props), Utils.getBufferSize(props), key, iv, streamOffset);
this(out, Utils.getCipherInstance(props), Utils.getBufferSize(props), key, iv, streamOffset);
}

public PositionedCryptoOutputStream(OutputStream out, Cipher cipher,
@@ -59,6 +58,6 @@ public PositionedCryptoOutputStream(Output output, Cipher cipher,
int bufferSize, byte[] key, byte[] iv, long streamOffset)
throws IOException {
super(output, cipher, bufferSize, key, iv, streamOffset);
Utils.checkPositionedStreamCipher(cipher);
Utils.checkStreamCipher(cipher);
}
}

0 comments on commit 57f6979

Please sign in to comment.