X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cadi%2Fcore%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fcadi%2FSymm.java;h=b1ec4cafaa9f7a5cc1bd6fc9a86296e294e1870b;hb=1296352d8eafee57f982a4342ad79ada4aa56d28;hp=afc1d979fe4a64ac3644a4906c9848465c455061;hpb=3aca33c5bb9af1ba4df574ceb90435f54d14ccf5;p=aaf%2Fauthz.git diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Symm.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Symm.java index afc1d979..b1ec4caf 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Symm.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Symm.java @@ -7,9 +7,9 @@ * Licensed 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. @@ -32,6 +32,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.util.ArrayList; +import java.util.Date; import java.util.Random; import javax.crypto.CipherInputStream; @@ -42,237 +43,238 @@ import org.onap.aaf.cadi.config.Config; /** * Key Conversion, primarily "Base64" - * + * * Base64 is required for "Basic Authorization", which is an important part of the overall CADI Package. - * - * Note: This author found that there is not a "standard" library for Base64 conversion within Java. - * The source code implementations available elsewhere were surprisingly inefficient, requiring, for + * + * Note: This author found that there is not a "standard" library for Base64 conversion within Java. + * The source code implementations available elsewhere were surprisingly inefficient, requiring, for * instance, multiple string creation, on a transaction pass. Integrating other packages that might be - * efficient enough would put undue Jar File Dependencies given this Framework should have none-but-Java + * efficient enough would put undue Jar File Dependencies given this Framework should have none-but-Java * dependencies. - * + * * The essential algorithm is good for a symmetrical key system, as Base64 is really just - * a symmetrical key that everyone knows the values. - * - * This code is quite fast, taking about .016 ms for encrypting, decrypting and even .08 for key - * generation. The speed quality, especially of key generation makes this a candidate for a short term token + * a symmetrical key that everyone knows the values. + * + * This code is quite fast, taking about .016 ms for encrypting, decrypting and even .08 for key + * generation. The speed quality, especially of key generation makes this a candidate for a short term token * used for identity. - * - * It may be used to easily avoid placing Clear-Text passwords in configurations, etc. and contains - * supporting functions such as 2048 keyfile generation (see keygen). This keyfile should, of course, - * be set to "400" (Unix) and protected as any other mechanism requires. - * - * However, this algorithm has not been tested against hackers. Until such a time, utilize more tested - * packages to protect Data, especially sensitive data at rest (long term). - * + * + * It may be used to easily avoid placing Clear-Text passwords in configurations, etc. and contains + * supporting functions such as 2048 keyfile generation (see keygen). This keyfile should, of course, + * be set to "400" (Unix) and protected as any other mechanism requires. + * + * AES Encryption is also employed to include standards. + * * @author Jonathan * */ public class Symm { - private static final byte[] DOUBLE_EQ = new byte[] {'=','='}; - public static final String ENC = "enc:"; - private static final Object LOCK = new Object(); - private static final SecureRandom random = new SecureRandom(); - - public final char[] codeset; - private final int splitLinesAt; - private final String encoding; - private final Convert convert; - private final boolean endEquals; - private byte[] keyBytes = null; - //Note: AES Encryption is not Thread Safe. It is Synchronized - //private AES aes = null; // only initialized from File, and only if needed for Passwords - - /** - * This is the standard base64 Key Set. - * RFC 2045 - */ - public static final Symm base64 = new Symm( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray() - ,76, Config.UTF_8,true); - - public static final Symm base64noSplit = new Symm( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray() - ,Integer.MAX_VALUE, Config.UTF_8,true); - - /** - * This is the standard base64 set suitable for URLs and Filenames - * RFC 4648 - */ - public static final Symm base64url = new Symm( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".toCharArray() - ,76, Config.UTF_8,true); - - /** - * A Password set, using US-ASCII - * RFC 4648 - */ - public static final Symm encrypt = new Symm(base64url.codeset,1024, "US-ASCII", false); - private static final byte[] EMPTY = new byte[0]; - - /** - * A typical set of Password Chars - * Note, this is too large to fit into the algorithm. Only use with PassGen - */ - private static char passChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+!@#$%^&*(){}[]?:;,.".toCharArray(); - - - private static Symm internalOnly = null; - - /** - * Use this to create special case Case Sets and/or Line breaks - * - * If you don't know why you need this, use the Singleton Method - * - * @param codeset - * @param split - */ - public Symm(char[] codeset, int split, String charset, boolean useEndEquals) { - this.codeset = codeset; - splitLinesAt = split; - encoding = charset; - endEquals = useEndEquals; - char prev = 0, curr=0, first = 0; - int offset=Integer.SIZE; // something that's out of range for integer array - - // There can be time efficiencies gained when the underlying keyset consists mainly of ordered - // data (i.e. abcde...). Therefore, we'll quickly analyze the keyset. If it proves to have - // too much entropy, the "Unordered" algorithm, which is faster in such cases is used. - ArrayList la = new ArrayList<>(); - for(int i=0;icodeset.length/3) { - convert = new Unordered(codeset); - } else { // too random to get speed enhancement from range algorithm - int[][] range = new int[la.size()][]; - la.toArray(range); - convert = new Ordered(range); - } - } - - public Symm copy(int lines) { - return new Symm(codeset,lines,encoding,endEquals); - } - - // Only used by keygen, which is intentionally randomized. Therefore, always use unordered - private Symm(char[] codeset, Symm parent) { - this.codeset = codeset; - splitLinesAt = parent.splitLinesAt; - endEquals = parent.endEquals; - encoding = parent.encoding; - convert = new Unordered(codeset); - } - - /** - * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc. - * @return - */ - @Deprecated - public static final Symm base64() { - return base64; - } - - /** - * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc. - * No Line Splitting - * @return - */ - @Deprecated - public static final Symm base64noSplit() { - return base64noSplit; - } - - /** - * Obtain the base64 "URL" behavior of this class, for use in File Names, etc. (no "/") - */ - @Deprecated - public static final Symm base64url() { - return base64url; - } - - /** - * Obtain a special ASCII version for Scripting, with base set of base64url use in File Names, etc. (no "/") - */ - public static final Symm baseCrypt() { - return encrypt; - } - - public T exec(SyncExec exec) throws Exception { - synchronized(LOCK) { - if(keyBytes == null) { - keyBytes = new byte[AES.AES_KEY_SIZE/8]; - int offset = (Math.abs(codeset[0])+47)%(codeset.length-keyBytes.length); - for(int i=0;i { - public T exec(Encryption enc) throws IOException, Exception; - } - + private static final byte[] DOUBLE_EQ = new byte[] {'=','='}; + public static final String ENC = "enc:"; + private static final Object LOCK = new Object(); + private static final SecureRandom random = new SecureRandom(); + + public final char[] codeset; + private final int splitLinesAt; + private final String encoding; + private final Convert convert; + private final boolean endEquals; + private byte[] keyBytes = null; + //Note: AES Encryption is not Thread Safe. It is Synchronized + //private AES aes = null; // only initialized from File, and only if needed for Passwords + private String name; + + /** + * This is the standard base64 Key Set. + * RFC 2045 + */ + public static final Symm base64 = new Symm( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray() + ,76, Config.UTF_8,true, "Base64"); + + public static final Symm base64noSplit = new Symm( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray() + ,Integer.MAX_VALUE, Config.UTF_8,true, "Base64, no Split"); + + /** + * This is the standard base64 set suitable for URLs and Filenames + * RFC 4648 + */ + public static final Symm base64url = new Symm( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".toCharArray() + ,76, Config.UTF_8,true, "Base64 for URL"); + + /** + * A Password set, using US-ASCII + * RFC 4648 + */ + public static final Symm encrypt = new Symm(base64url.codeset,1024, "US-ASCII", false, "Base64, 1024 size"); + private static final byte[] EMPTY = new byte[0]; + + /** + * A typical set of Password Chars + * Note, this is too large to fit into the algorithm. Only use with PassGen + */ + private static char passChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+!@#$%^&*(){}[]?:;,.".toCharArray(); + + + private static Symm internalOnly = null; + + /** + * Use this to create special case Case Sets and/or Line breaks + * + * If you don't know why you need this, use the Singleton Method + * + * @param codeset + * @param split + */ + public Symm(char[] codeset, int split, String charset, boolean useEndEquals, String name) { + this.codeset = codeset; + splitLinesAt = split; + encoding = charset; + endEquals = useEndEquals; + this.name = name; + char prev = 0, curr=0, first = 0; + int offset=Integer.SIZE; // something that's out of range for integer array + + // There can be time efficiencies gained when the underlying keyset consists mainly of ordered + // data (i.e. abcde...). Therefore, we'll quickly analyze the keyset. If it proves to have + // too much entropy, the "Unordered" algorithm, which is faster in such cases is used. + ArrayList la = new ArrayList<>(); + for (int i=0;icodeset.length/3) { + convert = new Unordered(codeset); + } else { // too random to get speed enhancement from range algorithm + int[][] range = new int[la.size()][]; + la.toArray(range); + convert = new Ordered(range); + } + } + + public Symm copy(int lines) { + return new Symm(codeset,lines,encoding,endEquals, "Copied " + lines); + } + + // Only used by keygen, which is intentionally randomized. Therefore, always use unordered + private Symm(char[] codeset, Symm parent) { + this.codeset = codeset; + splitLinesAt = parent.splitLinesAt; + endEquals = parent.endEquals; + encoding = parent.encoding; + convert = new Unordered(codeset); + } + + /** + * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc. + * @return + */ + @Deprecated + public static final Symm base64() { + return base64; + } + + /** + * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc. + * No Line Splitting + * @return + */ + @Deprecated + public static final Symm base64noSplit() { + return base64noSplit; + } + + /** + * Obtain the base64 "URL" behavior of this class, for use in File Names, etc. (no "/") + */ + @Deprecated + public static final Symm base64url() { + return base64url; + } + + /** + * Obtain a special ASCII version for Scripting, with base set of base64url use in File Names, etc. (no "/") + */ + public static final Symm baseCrypt() { + return encrypt; + } + + public T exec(SyncExec exec) throws Exception { + synchronized(LOCK) { + if (keyBytes == null) { + keyBytes = new byte[AES.AES_KEY_SIZE/8]; + int offset = (Math.abs(codeset[0])+47)%(codeset.length-keyBytes.length); + for (int i=0;i { + public T exec(Encryption enc) throws IOException, Exception; + } + public byte[] encode(byte[] toEncrypt) throws IOException { - if(toEncrypt==null) { - return EMPTY; - } else { - ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(toEncrypt.length*1.25)); - encode(new ByteArrayInputStream(toEncrypt),baos); - return baos.toByteArray(); - } - } + if (toEncrypt==null) { + return EMPTY; + } else { + ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(toEncrypt.length*1.25)); + encode(new ByteArrayInputStream(toEncrypt),baos); + return baos.toByteArray(); + } + } public byte[] decode(byte[] encrypted) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(encrypted.length*1.25)); - decode(new ByteArrayInputStream(encrypted),baos); - return baos.toByteArray(); - } + ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(encrypted.length*1.25)); + decode(new ByteArrayInputStream(encrypted),baos); + return baos.toByteArray(); + } - /** + /** * Helper function for String API of "Encode" * use "getBytes" with appropriate char encoding, etc. - * + * * @param str * @return * @throws IOException */ public String encode(String str) throws IOException { - byte[] array; - boolean useDefaultEncoding = false; - try { - array = str.getBytes(encoding); - } catch (IOException e) { - array = str.getBytes(); // take default - useDefaultEncoding = true; - } - // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code - ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*1.363)); // account for 4 bytes for 3 and a byte or two more - - encode(new ByteArrayInputStream(array),baos); - if (useDefaultEncoding) { - return baos.toString(); - } - return baos.toString(encoding); + byte[] array; + boolean useDefaultEncoding = false; + try { + array = str.getBytes(encoding); + } catch (IOException e) { + array = str.getBytes(); // take default + useDefaultEncoding = true; + } + // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code + ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*1.363)); // account for 4 bytes for 3 and a byte or two more + + encode(new ByteArrayInputStream(array),baos); + if (useDefaultEncoding) { + return baos.toString(); + } + return baos.toString(encoding); } - + /** * Helper function for the String API of "Decode" * use "getBytes" with appropriate char encoding, etc. @@ -281,161 +283,161 @@ public class Symm { * @throws IOException */ public String decode(String str) throws IOException { - byte[] array; - boolean useDefaultEncoding = false; - try { - array = str.getBytes(encoding); - } catch (IOException e) { - array = str.getBytes(); // take default - useDefaultEncoding = true; - } - // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code - ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*.76)); // Decoding is 3 bytes for 4. Allocate slightly more than 3/4s - decode(new ByteArrayInputStream(array), baos); - if (useDefaultEncoding) { - return baos.toString(); - } - return baos.toString(encoding); - } - - /** + byte[] array; + boolean useDefaultEncoding = false; + try { + array = str.getBytes(encoding); + } catch (IOException e) { + array = str.getBytes(); // take default + useDefaultEncoding = true; + } + // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code + ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*.76)); // Decoding is 3 bytes for 4. Allocate slightly more than 3/4s + decode(new ByteArrayInputStream(array), baos); + if (useDefaultEncoding) { + return baos.toString(); + } + return baos.toString(encoding); + } + + /** * Convenience Function - * + * * encode String into InputStream and call encode(InputStream, OutputStream) - * + * * @param string * @param out * @throws IOException */ - public void encode(String string, OutputStream out) throws IOException { - encode(new ByteArrayInputStream(string.getBytes()),out); - } - - /** - * Convenience Function - * - * encode String into InputStream and call decode(InputStream, OutputStream) - * - * @param string - * @param out - * @throws IOException - */ - public void decode(String string, OutputStream out) throws IOException { - decode(new ByteArrayInputStream(string.getBytes()),out); - } + public void encode(String string, OutputStream out) throws IOException { + encode(new ByteArrayInputStream(string.getBytes()),out); + } + + /** + * Convenience Function + * + * encode String into InputStream and call decode(InputStream, OutputStream) + * + * @param string + * @param out + * @throws IOException + */ + public void decode(String string, OutputStream out) throws IOException { + decode(new ByteArrayInputStream(string.getBytes()),out); + } public void encode(InputStream is, OutputStream os, byte[] prefix) throws IOException { - os.write(prefix); - encode(is,os); + os.write(prefix); + encode(is,os); } - /** + /** * encode InputStream onto Output Stream - * + * * @param is * @param estimate * @return * @throws IOException */ public void encode(InputStream is, OutputStream os) throws IOException { - // StringBuilder sb = new StringBuilder((int)(estimate*1.255)); // try to get the right size of StringBuilder from start.. slightly more than 1.25 times - int prev=0; - int read, idx=0, line=0; - boolean go; - do { - read = is.read(); - if(go = read>=0) { - if(line>=splitLinesAt) { - os.write('\n'); - line = 0; - } - switch(++idx) { // 1 based reading, slightly faster ++ - case 1: // ptr is the first 6 bits of read - os.write(codeset[read>>2]); - prev = read; - break; - case 2: // ptr is the last 2 bits of prev followed by the first 4 bits of read - os.write(codeset[((prev & 0x03)<<4) | (read>>4)]); - prev = read; - break; - default: //(3+) - // Char 1 is last 4 bits of prev plus the first 2 bits of read - // Char 2 is the last 6 bits of read - os.write(codeset[(((prev & 0xF)<<2) | (read>>6))]); - if(line==splitLinesAt) { // deal with line splitting for two characters - os.write('\n'); - line=0; - } - os.write(codeset[(read & 0x3F)]); - ++line; - idx = 0; - prev = 0; - } - ++line; - } else { // deal with any remaining bits from Prev, then pad - switch(idx) { - case 1: // just the last 2 bits of prev - os.write(codeset[(prev & 0x03)<<4]); - if(endEquals)os.write(DOUBLE_EQ); - break; - case 2: // just the last 4 bits of prev - os.write(codeset[(prev & 0xF)<<2]); - if(endEquals)os.write('='); - break; - } - idx = 0; - } - - } while(go); + // StringBuilder sb = new StringBuilder((int)(estimate*1.255)); // try to get the right size of StringBuilder from start.. slightly more than 1.25 times + int prev=0; + int read, idx=0, line=0; + boolean go; + do { + read = is.read(); + if (go = read>=0) { + if (line>=splitLinesAt) { + os.write('\n'); + line = 0; + } + switch(++idx) { // 1 based reading, slightly faster ++ + case 1: // ptr is the first 6 bits of read + os.write(codeset[read>>2]); + prev = read; + break; + case 2: // ptr is the last 2 bits of prev followed by the first 4 bits of read + os.write(codeset[((prev & 0x03)<<4) | (read>>4)]); + prev = read; + break; + default: //(3+) + // Char 1 is last 4 bits of prev plus the first 2 bits of read + // Char 2 is the last 6 bits of read + os.write(codeset[(((prev & 0xF)<<2) | (read>>6))]); + if (line==splitLinesAt) { // deal with line splitting for two characters + os.write('\n'); + line=0; + } + os.write(codeset[(read & 0x3F)]); + ++line; + idx = 0; + prev = 0; + } + ++line; + } else { // deal with any remaining bits from Prev, then pad + switch(idx) { + case 1: // just the last 2 bits of prev + os.write(codeset[(prev & 0x03)<<4]); + if (endEquals)os.write(DOUBLE_EQ); + break; + case 2: // just the last 4 bits of prev + os.write(codeset[(prev & 0xF)<<2]); + if (endEquals)os.write('='); + break; + } + idx = 0; + } + + } while (go); } public void decode(InputStream is, OutputStream os, int skip) throws IOException { - if(is.skip(skip)!=skip) { - throw new IOException("Error skipping on IOStream in Symm"); - } - decode(is,os); + if (is.skip(skip)!=skip) { + throw new IOException("Error skipping on IOStream in Symm"); + } + decode(is,os); } /** - * Decode InputStream onto OutputStream - * @param is - * @param os - * @throws IOException - */ + * Decode InputStream onto OutputStream + * @param is + * @param os + * @throws IOException + */ public void decode(InputStream is, OutputStream os) throws IOException { - int read, idx=0; - int prev=0, index; - while((read = is.read())>=0) { - index = convert.convert(read); - if(index>=0) { - switch(++idx) { // 1 based cases, slightly faster ++ - case 1: // index goes into first 6 bits of prev - prev = index<<2; - break; - case 2: // write second 2 bits of into prev, write byte, last 4 bits go into prev - os.write((byte)(prev|(index>>4))); - prev = index<<4; - break; - case 3: // first 4 bits of index goes into prev, write byte, last 2 bits go into prev - os.write((byte)(prev|(index>>2))); - prev = index<<6; - break; - default: // (3+) | prev and last six of index - os.write((byte)(prev|(index&0x3F))); - idx = prev = 0; - } - } - }; - os.flush(); + int read, idx=0; + int prev=0, index; + while ((read = is.read())>=0) { + index = convert.convert(read); + if (index>=0) { + switch(++idx) { // 1 based cases, slightly faster ++ + case 1: // index goes into first 6 bits of prev + prev = index<<2; + break; + case 2: // write second 2 bits of into prev, write byte, last 4 bits go into prev + os.write((byte)(prev|(index>>4))); + prev = index<<4; + break; + case 3: // first 4 bits of index goes into prev, write byte, last 2 bits go into prev + os.write((byte)(prev|(index>>2))); + prev = index<<6; + break; + default: // (3+) | prev and last six of index + os.write((byte)(prev|(index&0x3F))); + idx = prev = 0; + } + } + }; + os.flush(); } - + /** * Interface to allow this class to choose which algorithm to find index of character in Key * @author Jonathan * */ private interface Convert { - public int convert(int read) throws IOException; + public int convert(int read) throws IOException; } /** @@ -445,29 +447,29 @@ public class Symm { * */ private static final class Ordered implements Convert { - private int[][] range; - public Ordered(int[][] range) { - this.range = range; - } - public int convert(int read) throws IOException { - // System.out.print((char)read); - switch(read) { - case -1: - case '=': - case ' ': - case '\n': - case '\r': - return -1; - } - for(int i=0;i= range[i][0] && read<=range[i][1]) { - return read-range[i][2]; - } - } - throw new IOException("Unacceptable Character in Stream"); - } + private int[][] range; + public Ordered(int[][] range) { + this.range = range; + } + public int convert(int read) throws IOException { + // System.out.print((char)read); + switch(read) { + case -1: + case '=': + case ' ': + case '\n': + case '\r': + return -1; + } + for (int i=0;i= range[i][0] && read<=range[i][1]) { + return read-range[i][2]; + } + } + throw new IOException("Unacceptable Character in Stream"); + } } - + /** * Unordered, i.e. the key is purposely randomized, simply has to investigate each character * until we find a match. @@ -475,415 +477,429 @@ public class Symm { * */ private static final class Unordered implements Convert { - private char[] codec; - public Unordered(char[] codec) { - this.codec = codec; - } - public int convert(int read) throws IOException { - switch(read) { - case -1: - case '=': - case '\n': - case '\r': - return -1; - } - for(int i=0;i() { - @Override - public Void exec(Encryption enc) throws Exception { - CipherInputStream cis = enc.inputStream(new ByteArrayInputStream(baos.toByteArray()), true); - try { - encode(cis,os); - } finally { - os.flush(); - cis.close(); - } - return null; - } - }); - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new IOException(e); - } - } + if (password==null) { + throw new IOException("Invalid password passed"); + } + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + byte[] bytes = password.getBytes(); + if (this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization + dos.write(bytes); + } else { + + Random r = new SecureRandom(); + int start = 0; + byte b; + for (int i=0;i<3;++i) { + dos.writeByte(b=(byte)r.nextInt()); + start+=Math.abs(b); + } + start%=0x7; + for (int i=0;i() { + @Override + public Void exec(Encryption enc) throws Exception { + CipherInputStream cis = enc.inputStream(new ByteArrayInputStream(baos.toByteArray()), true); + try { + encode(cis,os); + } finally { + os.flush(); + cis.close(); + } + return null; + } + }); + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOException(e); + } + } /** * Decrypt a password into a String - * + * * Convenience method - * + * * @param password * @return * @throws IOException */ public String depass(String password) throws IOException { - if(password==null)return null; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - depass(password,baos); - return new String(baos.toByteArray()); + if (password==null)return null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + depass(password,baos); + return new String(baos.toByteArray()); } - + /** * Decrypt a password - * + * * Skip Symm.ENC - * + * * @param password * @param os * @return * @throws IOException */ public long depass(final String password, final OutputStream os) throws IOException { - int offset = password.startsWith(ENC)?4:0; - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final ByteArrayInputStream bais = new ByteArrayInputStream(password.getBytes(),offset,password.length()-offset); - try { - exec(new SyncExec() { - @Override - public Void exec(Encryption enc) throws IOException { - CipherOutputStream cos = enc.outputStream(baos, false); - decode(bais,cos); - cos.close(); // flush - return null; - } - }); - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new IOException(e); - } - - byte[] bytes = baos.toByteArray(); - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes)); - long time; - if(this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization - os.write(bytes); - time = 0L; - } else { - int start=0; - for(int i=0;i<3;++i) { - start+=Math.abs(dis.readByte()); - } - start%=0x7; - for(int i=0;i() { + @Override + public Void exec(Encryption enc) throws IOException { + CipherOutputStream cos = enc.outputStream(baos, false); + decode(bais,cos); + cos.close(); // flush + return null; + } + }); + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOException(e); + } + + byte[] bytes = baos.toByteArray(); + DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes)); + long time; + if (this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization + os.write(bytes); + time = 0L; + } else { + int start=0; + for (int i=0;i<3;++i) { + start+=Math.abs(dis.readByte()); + } + start%=0x7; + for (int i=0;i=0) { - index = o.next(); - if(index<0 || index>=codeset.length) { - System.out.println("uh, oh"); - } - if(right) { // alternate going left or right to find the next open slot (keeps it from taking too long to hit something) - for(int j=index;j=0;--j) { - if(seq[j]==0) { - seq[j]=codeset[filled]; - --filled; - break; - } - } - right = true; - } - } - Symm newSymm = new Symm(seq,this); - // Set the KeyBytes - try { - newSymm.keyBytes = new byte[AES.AES_KEY_SIZE/8]; - int offset = (Math.abs(key[(47%key.length)])+137)%(key.length-newSymm.keyBytes.length); - for(int i=0;i=0) { + index = o.next(); + if (index<0 || index>=codeset.length) { + System.out.println("uh, oh"); + } + if (right) { // alternate going left or right to find the next open slot (keeps it from taking too long to hit something) + for (int j=index;j=0;--j) { + if (seq[j]==0) { + seq[j]=codeset[filled]; + --filled; + break; + } + } + right = true; + } + } + Symm newSymm = new Symm(seq,this); + newSymm.name = "from bytes"; + // Set the KeyBytes + try { + newSymm.keyBytes = new byte[AES.AES_KEY_SIZE/8]; + int offset = (Math.abs(key[(47%key.length)])+137)%(key.length-newSymm.keyBytes.length); + for (int i=0;i