Permalink
Browse files

added encryption, tested.

minor fixes for SoftClips. Works for one of the cancer files.
  • Loading branch information...
1 parent 17ec627 commit 45993234c94ec9da1d4b2788f4d4ad950ef6810b @vadimzalunin committed Nov 9, 2012
View
@@ -1,11 +1,12 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src/main/java"/>
- <classpathentry kind="src" path="src/test/java"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
- <classpathentry kind="lib" path="lib/jcommander-1.7.jar"/>
- <classpathentry kind="lib" path="lib/sam-1.79.jar"/>
- <classpathentry kind="lib" path="lib/picard-1.79.jar"/>
- <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/test/java"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="lib" path="lib/jcommander-1.7.jar"/>
+ <classpathentry kind="lib" path="lib/sam-1.79.jar"/>
+ <classpathentry kind="lib" path="lib/picard-1.79.jar"/>
+ <classpathentry kind="lib" path="lib/ega-Cipher.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
View
@@ -1,3 +1,3 @@
#Build Number for ANT. Do not edit!
-#Thu Nov 08 16:45:34 GMT 2012
-build.number=11
+#Fri Nov 09 10:14:49 GMT 2012
+build.number=25
View
Binary file not shown.
View
Binary file not shown.
@@ -0,0 +1,81 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package uk.ac.ebi.embl.ega_cipher;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ *
+ * @author asenf
+ */
+public class CipherInputStream_256 {
+ private Cipher cipher;
+ private InputStream is;
+ private int pw_strength;
+
+ public CipherInputStream_256(InputStream in, char[] password, int pw_strength) {
+ this.pw_strength = pw_strength;
+
+ try {
+ this.is = new BufferedInputStream(in);
+
+ // Key Generation
+ byte[] salt = {(byte)-12, (byte)34, (byte)1, (byte)0, (byte)-98, (byte)223, (byte)78, (byte)21};
+ SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+ KeySpec spec = new PBEKeySpec(password, salt, 1024, this.pw_strength); // Password Strength - n bits
+ SecretKey tmp = factory.generateSecret(spec);
+ SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
+
+ // Initialization Vector
+ byte[] random_iv = new byte[16];
+ try {
+ this.is.read(random_iv, 0, 16);
+ } catch (IOException ex) {
+ Logger.getLogger(CipherInputStream_256.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ AlgorithmParameterSpec paramSpec = new IvParameterSpec(random_iv);
+
+ // Cipher Setup
+ cipher = Cipher.getInstance("AES/CTR/NoPadding"); // load a cipher AES / Segmented Integer Counter
+ cipher.init(Cipher.DECRYPT_MODE, secret, paramSpec);
+
+ } catch (InvalidAlgorithmParameterException ex) {
+ Logger.getLogger(CipherInputStream_256.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (InvalidKeySpecException ex) {
+ Logger.getLogger(CipherInputStream_256.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (InvalidKeyException ex) {
+ Logger.getLogger(CipherInputStream_256.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (NoSuchPaddingException ex) {
+ Logger.getLogger(CipherInputStream_256.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (NoSuchAlgorithmException ex) {
+ Logger.getLogger(CipherInputStream_256.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ public InputStream getCipherInputStream() {
+ CipherInputStream in = null;
+ in = new CipherInputStream(is, cipher);
+
+ return in;
+ }
+}
@@ -0,0 +1,187 @@
+/*
+ * This class extends a SeekableStream and is used for random access to
+ * encrypted files. This class is not used to encrypt files. Only seek()
+ * and read() functionality is implemented.
+ * This class is used by the Secure HTTPS Server to deliver unencrypted
+ * portions of BAM files.
+ */
+package uk.ac.ebi.embl.ega_cipher;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+import uk.ac.ebi.embl.ega_cipher.CipherStream_256;
+import net.sf.samtools.util.SeekableStream;
+
+/**
+ *
+ * @author asenf
+ */
+public class SeekableCipherStream_256 extends SeekableStream {
+
+ public static final int DEFAULT_BUFFER_SIZE = 512000;
+
+ final SeekableStream wrappedStream;
+ Cipher cipher;
+ CipherInputStream incipher;
+ long position;
+ SecretKey skey_;
+ byte[] orig_digest; // Original IV\
+ int pw_strength;
+
+ public SeekableCipherStream_256(SeekableStream in, char[] password, int bufferSize) {
+ this(in, password, bufferSize, 256);
+ }
+ public SeekableCipherStream_256(SeekableStream in, char[] password, int bufferSize, int pw_strength) {
+ this.wrappedStream = in;
+ this.position = 0;
+ this.pw_strength = pw_strength;
+
+ // Initialization Vector
+ byte[] iv = new byte[16];
+ try {
+ in.read(iv, 0, 16);
+ } catch (IOException ex) {
+ Logger.getLogger(SeekableCipherStream_256.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ this.orig_digest = new byte[16];
+ System.arraycopy(iv,0, this.orig_digest, 0, 16);
+
+ this.cipher = CipherStream_256.getCipher(password, false, pw_strength, this.orig_digest);
+ this.incipher = new CipherInputStream(this.wrappedStream, cipher);
+ }
+ public SeekableCipherStream_256(SeekableStream in, char[] password) {
+ this(in, password, DEFAULT_BUFFER_SIZE);
+ }
+
+ @Override
+ public void seek(long position) throws IOException {
+ this.position = position;
+ this.wrappedStream.seek(position+16);
+
+ // Set position to start of current enclosing block
+ long position1 = ( position / 16 ) * 16; // Only based on AES Block Size of 16 bytes!
+
+ // Reset the initialization vector to the correct block
+ byte[] newIV = new byte[this.orig_digest.length];
+ System.arraycopy(this.orig_digest, 0, newIV, 0, this.orig_digest.length); // preserved start value
+ byte_increment_fast(newIV, position1); // is there a better way??
+ IvParameterSpec ivSpec_new = new IvParameterSpec(newIV);
+ try {
+ this.cipher.init(Cipher.ENCRYPT_MODE, this.skey_, ivSpec_new);
+ } catch (InvalidKeyException ex) {
+ Logger.getLogger(SeekableCipherStream_256.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (InvalidAlgorithmParameterException ex) {
+ Logger.getLogger(SeekableCipherStream_256.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ this.incipher = new CipherInputStream(this.wrappedStream, cipher);
+ }
+ private static void byte_increment_fast(byte[] data, long increment) {
+ long countdown = increment / 16; // Count number of block updates
+
+ ArrayList<Integer> digits_ = new ArrayList<Integer>();
+ int cnt = 0; long d = 256, cn = 0;
+ while (countdown > cn && d > 0) {
+ int l = (int) ((countdown % d) / (d/256));
+ digits_.add(l);
+ cn += (l*(d/256));
+ d *= 256;
+ }
+ int size = digits_.size();
+ int[] digits = new int[size];
+ for (int i=0; i<size; i++) {
+ digits[size-1-i] = digits_.get(i).intValue();
+ }
+
+ int cur_pos = data.length-1, carryover = 0, delta = data.length-digits.length;
+
+ for (int i=cur_pos; i>=delta; i--) { // Work on individual digits
+ int digit = digits[i-delta] + carryover; // convert to integer
+ int place = (int)(data[i]&0xFF); // convert data[] to integer
+ int new_place = digit+place;
+ if (new_place >= 256) carryover=1; else carryover=0;
+ data[i] = (byte) (new_place % 256);
+ }
+
+ // Deal with potential last carryovers
+ cur_pos -= digits.length;
+ while (carryover == 1 && cur_pos>= 0) {
+ data[cur_pos]++;
+ if (data[cur_pos]==0) carryover=1; else carryover=0;
+ cur_pos--;
+ }
+ }
+
+ @Override
+ public long length() {
+ return this.wrappedStream.length()-16; // subtract prepended IV
+ }
+
+ @Override
+ public int read(byte[] buffer, int offset, int length) throws IOException {
+ long position1 = ( (this.position+offset) / 16 ) * 16; // Only based on AES Block Size of 16 bytes! block-correct start pos
+ long p = this.position; // remember desired start
+ seek(position1); // position at block-correct start to enable AES decryption
+
+ int delta = (int) ((p+offset) - position1); // gap between block start and desired start
+ byte[] buf = new byte[length+delta]; // enough to hold all data plus delta
+
+ int n = 0; // number of read bytes
+ int length1 = length + delta;
+ while (n < length1) {
+ //System.out.println(buf.length + "\t" + n + "\t" + (length1-n) + "\t" + length1);
+ final int count = this.incipher.read(buf, n, length1-n); // read into buffer directly; offset later will be: delta
+ if (count < 0) {
+ System.arraycopy(buf, delta, buffer, offset, (n-delta));
+ return (n-delta);
+ }
+ n += count;
+ }
+ seek(p); // Reset actual position
+
+ System.arraycopy(buf, delta, buffer, offset, length);
+ assert (n-delta == length); // must match length
+
+ this.position += length;
+ return (n-delta);
+ }
+
+ @Override
+ public void close() throws IOException {
+ this.wrappedStream.close();
+ }
+
+ @Override
+ public boolean eof() throws IOException {
+ return this.position >= this.wrappedStream.length();
+ }
+
+ @Override
+ public String getSource() {
+ return this.wrappedStream.getSource();
+ }
+
+ @Override
+ public int read() throws IOException {
+ byte[] buf = new byte[16];
+
+ long position1 = ( (this.position) / 16 ) * 16;
+ long p = this.position;
+ seek(position1);
+
+ this.incipher.read(buf);
+
+ int offset = (int)(p-position1);
+ seek(p+1);
+
+ return (int)(buf[offset]&0xFF); // return a proper int
+ }
+}
Oops, something went wrong.

0 comments on commit 4599323

Please sign in to comment.