I have a coworker that just bought a second 360 so that he could stream Netflix to his second TV. However, there is a gottcha... It seems that since the Netflix service is tied to your Xbox Live account and that the movies can only be streamed to the console that has your profile. I suppose you could just swap out the hard drive. The other option is to have a second live account.
Microsoft you are on the brink of secondary resurgence in the sales of the 360 if you can solve this problem. I know many people that are looking for a TV box that will do HD, play DVDs, stream from Netflix, stream media from PCs, and play games. I should not have to have a second live account to make this happen.
Monday, January 26, 2009
Friday, January 23, 2009
Hiding software on Windows PC
This is an excellent article on the capabilities of ad ware
http://philosecurity.org/2009/01/12/interview-with-an-adware-author
http://philosecurity.org/2009/01/12/interview-with-an-adware-author
Labels:
security
Thursday, January 22, 2009
Securing keystores II
So in Securing Keystores I, I discussed wrapping keys using the key wrap techniques in the rfc3394 specification. However, I left something out of that article... the wrapping class.
Below is a partial listing for the class that handles this work the RSA Encrypter. One thing to notice is the embedded public and private key. This "ties" the keystore to the class. To do an offline attack, not only would you have to have the encrypted files, the keystore and the keystore password, you would also have to have this class to be able to unwrap the keys. This goes against the conventional notion of embedding keys in software.
snip...
Below is a partial listing for the class that handles this work the RSA Encrypter. One thing to notice is the embedded public and private key. This "ties" the keystore to the class. To do an offline attack, not only would you have to have the encrypted files, the keystore and the keystore password, you would also have to have this class to be able to unwrap the keys. This goes against the conventional notion of embedding keys in software.
snip...
import java.io.InputStream; import java.io.ByteArrayInputStream; import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.SecretKey; import com.Ostermiller.util.Base64; import java.security.PublicKey; import java.security.PrivateKey; import java.security.Key; import java.security.KeyFactory; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import net.app.exception.AppException; public class RsaEncrypter { private Cipher ecipher; private Cipher dcipher; private PublicKey publicKey; private PrivateKey privateKey; public RsaEncrypter(PublicKey aPublicKey, PrivateKey aPrivateKey) throws AppException { try { if ((aPublicKey == null) && (aPrivateKey == null)) { byte[] base64PublicKey = {'M','I','I','B','I','j','A','N','B','g','k','q','h','k','i','G','9','w','0','B','A','Q','E','F','A','A','O','C','A','Q','8','A','M','I','I','B','C','g','K','C','A','Q','E','A','q','m','j','X','K','m','l','s','U','G','y','5','Q','g','h','Q','u','R','0','I','Z','g','O','d','1','W','Q','Z','e','O','i','j', 'a','X','a','z','J','p','Z','U','b','+','k','2','E','g','l','y','O','q','V','D','i','d','k','Z','f','0','C','1','Z','J','D','+','W','l','K','F','f','Q','J','2','P','B','U','v','A','p','7','u','f','9','E','f','i','w','T','N','B','B','m','3','J','q','7','R','G','L','N','a','+','g','s','F','9','f','n','+', 'b','/','r','6','P','h','Z','l','7','W','i','Z','c','I','u','x','D','q','x','Y','Z','M','Y','t','6','r','0','6','l','3','Y','x','l','/','j','5','h','q','M','e','B','D','E','F','X','k','x','h','6','6','A','o','3','9','z','a','7','N','0','O','q','X','B','/','c','E','U','P','D','s','v','Z','d','d','E','N', 'S','E','1','o','/','5','c','g','v','+','y','V','O','W','C','6','C','4','E','h','6','5','l','R','N','N','W','l','k','8','r','4','g','p','+','3','u','R','d','+','i','e','U','K','f','h','v','i','E','k','b','q','o','q','c','5','B','2','y','J','K','i','v','u','J','C','B','Y','V','n','d','7','3','w','n','R', 'G','1','Y','/','a','9','a','w','Q','E','8','N','y','z','h','p','U','B','E','U','b','M','v','d','Z','G','I','Y','E','r','5','X','y','H','b','j','6','Z','R','X','V','V','E','T','/','l','S','g','/','E','Q','d','O','+','4','V','e','g','W','X','J','v','A','n','b','4','d','m','O','t','9','x','A','Q','4','z', 'Z','m','y','B','J','w','I','D','A','Q','A','B'} byte[] base64PrivateKey = {'M','I','I','E','v','A','I','B','A','D','A','N','B','g','k','q','h','k','i','G','9','w','0','B','A','Q','E','F','A','A','S','C','B','K','Y','w','g','g','S','i','A','g','E','A','A','o','I','B','A','Q','C','q','a','N','c','q','a','W','x','Q','b','L','l','C','C','F','C','5','H','Q','h','m','A','5','3','V', 'Z','B','l','4','6','K','N','p','d','r','M','m','l','l','R','v','6','T','Y','S','C','X','I','6','p','U','O','J','2','R','l','/','Q','L','V','k','k','P','5','a','U','o','V','9','A','n','Y','8','F','S','8','C','n','u','5','/','0','R','+','L','B','M','0','E','G','b','c','m','r','t','E','Y','s','1','r','6', 'C','w','X','1','+','f','5','v','+','v','o','+','F','m','X','t','a','J','l','w','i','7','E','O','r','F','h','k','x','i','3','q','v','T','q','X','d','j','G','X','+','P','m','G','o','x','4','E','M','Q','V','e','T','G','H','r','o','C','j','f','3','N','r','s','3','Q','6','p','c','H','9','w','R','Q','8','O', 'y','9','l','1','0','Q','1','I','T','W','j','/','l','y','C','/','7','J','U','5','Y','L','o','L','g','S','H','r','m','V','E','0','1','a','W','T','y','v','i','C','n','7','e','5','F','3','6','J','5','Q','p','+','G','+','I','S','R','u','q','i','p','z','k','H','b','I','k','q','K','+','4','k','I','F','h','W', 'd','3','v','f','C','d','E','b','V','j','9','r','1','r','B','A','T','w','3','L','O','G','l','Q','E','R','R','s','y','9','1','k','Y','h','g','S','v','l','f','I','d','u','P','p','l','F','d','V','U','R','P','+','V','K','D','8','R','B','0','7','7','h','V','6','B','Z','c','m','8','C','d','v','h','2','Y','6', '3','3','E','B','D','j','N','m','b','I','E','n','A','g','M','B','A','A','E','C','g','g','E','A','d','t','Z','M','D','q','i','c','P','2','3','C','t','9','j','i','q','m','U','j','w','T','i','O','b','g','y','z','c','s','0','R','g','G','+','l','u','a','g','m','V','D','D','X','Y','z','a','x','M','V','K','k', 'y','d','H','b','Z','R','G','0','L','e','C','r','c','E','O','S','E','b','6','Q','w','4','+','m','S','/','a','X','r','g','0','h','K','S','p','8','6','n','o','g','b','l','q','F','O','O','u','C','6','1','K','a','o','p','H','n','L','S','J','i','N','s','A','Z','7','r','j','+','I','C','1','a','m','T','f','5', 'I','L','X','P','u','Z','6','i','6','J','M','l','P','K','0','F','H','i','5','M','t','X','G','W','I','8','+','y','j','c','Y','Q','G','y','W','C','i','q','I','S','I','n','h','J','/','s','R','K','l','r','T','L','p','o','4','W','Q','q','M','k','v','N','F','v','y','c','Q','X','2','9','2','h','a','t','n','Y', 'I','N','f','q','M','w','9','s','5','u','t','A','t','D','A','t','0','d','o','q','e','c','O','t','e','9','U','p','P','v','z','+','O','l','H','Y','h','v','j','f','Q','t','R','j','K','D','i','N','D','f','g','0','C','U','O','H','K','E','b','z','G','G','3','Y','F','7','n','b','k','Z','s','x','e','4','e','Q', '3','D','p','f','K','R','M','C','7','Y','j','u','M','S','P','+','C','c','8','a','m','t','X','m','F','m','H','Z','F','r','n','d','M','W','Y','x','e','T','k','3','t','4','w','5','s','3','a','v','o','5','4','y','e','c','a','Z','4','t','1','G','i','Q','K','B','g','Q','D','x','8','9','a','V','G','b','I','z', 'L','H','E','L','K','7','P','G','r','x','w','z','A','M','I','P','a','b','U','R','t','C','n','F','G','a','A','p','m','F','+','O','L','T','q','L','r','d','s','M','l','B','w','F','o','g','5','3','f','n','u','P','L','x','4','O','l','j','p','7','6','D','J','U','o','z','f','B','5','Y','c','N','w','2','d','E', '1','/','K','V','C','P','Q','y','/','U','1','L','y','0','p','P','5','v','7','Y','S','h','/','e','H','M','b','+','A','i','8','B','S','+','m','2','S','K','2','T','z','q','t','a','z','N','g','n','E','E','Z','q','D','I','d','1','W','H','9','K','D','J','r','x','U','P','+','u','B','K','S','2','q','m','N','y', 'C','M','s','X','2','R','F','P','c','w','K','B','g','Q','C','0','T','a','c','d','l','z','O','6','Q','8','l','M','a','P','Y','m','Z','S','u','0','d','0','M','G','d','s','j','5','Q','B','3','Q','a','A','/','j','+','B','G','D','Y','G','b','a','k','L','q','Y','4','j','9','d','Z','F','s','m','5','n','M','1', 't','X','q','f','K','l','S','D','f','Y','k','d','v','J','9','j','7','4','g','D','3','Y','P','2','P','r','4','x','V','c','X','L','w','C','B','0','A','7','m','o','v','9','E','0','5','h','k','d','P','e','+','8','h','K','F','b','l','5','s','q','9','O','p','1','/','Q','a','j','S','s','3','N','v','t','S','k', 'F','P','E','L','x','s','H','U','i','0','v','N','I','u','W','m','q','W','D','B','a','3','5','m','A','H','N','w','M','S','r','y','f','Q','K','B','g','F','D','R','d','T','T','a','n','3','a','O','e','r','g','T','g','f','p','0','1','Y','O','H','1','k','q','V','s','a','D','X','Q','D','i','R','J','b','m','f', 'J','x','P','z','s','a','G','k','k','g','2','y','j','2','W','m','S','x','T','J','D','/','a','0','8','2','J','F','9','g','U','b','e','2','x','g','F','K','j','U','x','X','b','o','d','V','8','+','j','s','4','P','b','p','p','1','l','9','M','g','d','Z','M','Z','A','r','k','2','k','U','x','8','6','k','9','A', 'Z','X','k','W','Z','V','u','5','D','R','n','Z','J','8','2','t','r','O','n','n','e','s','3','D','n','5','+','n','z','u','T','q','L','v','s','6','Z','h','0','3','e','d','l','2','M','r','+','N','h','m','F','R','5','Y','F','X','A','o','G','A','Q','3','3','d','1','I','H','I','5','y','y','A','q','Y','2','Q', 't','o','a','g','e','Y','k','7','G','a','x','V','R','p','f','t','k','R','m','i','+','R','7','e','z','2','L','C','n','Y','Y','X','k','y','r','9','t','S','P','f','y','w','v','w','j','G','Z','G','Z','F','Y','g','F','K','h','l','L','z','B','w','K','a','R','8','M','Z','Y','1','0','3','N','h','F','m','6','Y', '/','9','A','H','V','e','Y','f','F','T','/','Y','P','A','j','1','1','b','B','d','k','R','/','E','l','t','i','F','S','O','s','s','6','M','W','y','O','m','X','B','7','A','Z','G','6','r','S','8','F','k','B','s','R','f','d','u','h','H','d','P','p','7','c','3','d','K','+','c','P','O','p','m','S','9','T','b', '0','r','E','C','g','Y','B','I','p','z','w','l','r','P','n','S','7','R','p','7','Z','y','7','U','R','m','Y','J','9','c','h','t','f','/','q','1','q','D','d','P','q','J','v','w','/','/','q','5','q','E','1','m','A','K','3','u','T','G','t','e','x','Z','x','F','q','g','2','m','Z','R','n','c','g','w','T','Y', 'X','1','B','g','D','k','0','7','Y','4','H','s','Q','3','A','F','T','S','0','H','x','h','J','f','U','Y','f','M','4','u','O','p','5','J','Y','Q','B','+','Z','8','o','Z','b','X','3','2','d','U','9','6','q','Z','f','L','5','Q','J','P','Y','h','r','O','H','b','i','i','8','x','O','I','r','N','G','T','O','Z', 'x','R','z','D','G','O','y','y','B','Z','q','a','0','5','D','0','T','n','/','Y','f','B','r','8','e','Q','=','='} byte[] pubKeyBytes = Base64.decode(base64PublicKey); byte[] privKeyBytes = Base64.decode(base64PrivateKey); X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(pubKeyBytes); PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privKeyBytes); KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA"); this.setPrivateKey( (PrivateKey)rsaKeyFactory.generatePrivate(privateKeySpec) ); this.setPublicKey( (PublicKey)rsaKeyFactory.generatePublic(publicKeySpec) ); } else { this.setPrivateKey( aPrivateKey ); this.setPublicKey( aPublicKey ); } // Instantiate the Ciphers ecipher = Cipher.getInstance("RSA"); dcipher = Cipher.getInstance("RSA"); ecipher.init(Cipher.ENCRYPT_MODE, publicKey); dcipher.init(Cipher.DECRYPT_MODE, privateKey); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); e.printStackTrace(); throw new AppException("Could not instantiate the RSA Encryption utility: " + e.getMessage()); } } public byte[] wrapKey(Key key) throws AppException { try { ecipher.init(Cipher.WRAP_MODE, publicKey); return ecipher.wrap(key); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); e.printStackTrace(); throw new AppException("Could not wrap the key: " + e.getMessage()); } } public Key unwrapKey(byte[] key) throws AppException { try { dcipher.init(Cipher.UNWRAP_MODE, privateKey); return dcipher.unwrap(key, "RSA", Cipher.SECRET_KEY ); } catch (Exception e) { System.out.println("Error: " + e.getMessage()); e.printStackTrace(); throw new AppException("Could not unwrap the key: " + e.getMessage()); } } public Cipher getEcipher() { return ecipher; } public Cipher getDcipher() { return dcipher; } public PublicKey getPublicKey() { return publicKey; } public void setPublicKey(PublicKey aPublicKey) { publicKey = aPublicKey; } public PrivateKey getPrivateKey() { return privateKey; } public void setPrivateKey(PrivateKey aPrivateKey) { privateKey = aPrivateKey; } Snip...
Labels:
encryption,
java,
keystore,
security
Password Complexity Regex
Here is a Password Complexity Regex that I came up with. It requires length of 8, at least one digit, one special character and mixed case. I have broken it across four lines to make it easy to read. Just take the carriage returns out if you want to use it.
Special chars that are allowed are @#!$%&+=-_
If you want to change the length of the password accepted, (say 12) alter the last term to read {12,}
Unlike IBM I won't try to patent it http://yro.slashdot.org/firehose.pl?id=4629161&op=view. You may use it freely.
Updated per comments by Cadacus ... Thanks!
(?=[@#!$%&+=\-_a-zA-Z0-9]*?[A-Z])
(?=[@#!$%&+=\-_a-zA-Z0-9]*?[a-z])
(?=[@#!$%&+=\-_a-zA-Z0-9]*?[0-9])
[@#!$%&+=\-_a-zA-Z0-9]{8,}
Special chars that are allowed are @#!$%&+=-_
If you want to change the length of the password accepted, (say 12) alter the last term to read {12,}
Unlike IBM I won't try to patent it http://yro.slashdot.org/firehose.pl?id=4629161&op=view. You may use it freely.
Updated per comments by Cadacus ... Thanks!
Tuesday, January 20, 2009
Threading for Performance I
I write a lot of jsp and servlet classes so I do not get to stretch my programming legs much. Recently I had the joy of threading a batch process that I wanted to speed up. This batch process was supposed to process all the files in the system. This could be upwards of 15,000 files. This process had to run fast so I new threading was applicable. Once I got into it I was surprised by how well threads were going to work out. This actually makes for a fairly easy algorithm. I can create a loop and spawn separate threads to work on each file. Since none of the files is shared and I can control the creation of threads I don't have to worry as much about the traditional thread gotchas like thread contention.
Since this process is kicked off by a Web request, I am creating a master thread that will spawn the worker threads in my loop. I want to do this so that I can allow the web request to return and report that the process has started. Each subsequent request should refresh a log page allowing the user to see the output from the threaded batch process.
My technique is to create my loop for all the files I want to process. As I spawn threads I want to check against a max number of threads I want running at any given time. I like to use 8
This is a very easy way to use the capabilities of threading to process the files faster. Come back for Threading for Performance II and I will discuss how to report on the threaded process to subsequent requests against the servlet.
Since this process is kicked off by a Web request, I am creating a master thread that will spawn the worker threads in my loop. I want to do this so that I can allow the web request to return and report that the process has started. Each subsequent request should refresh a log page allowing the user to see the output from the threaded batch process.
My technique is to create my loop for all the files I want to process. As I spawn threads I want to check against a max number of threads I want running at any given time. I like to use 8
This will process all the documents by firing off 8 worker threads at a time. Once all 8 are finished then 8 more are kicked of until the pool of files is depleted. This allows me to tune the number of files being processed at any one time.
Worker worker = null;
Iteratorit = documents.iterator();
int threadCount = 0;
//loop until documents are exhausted
while ( true )
{
// comment the sleep to
// allow full speed processing.
// it is used to simulate a long processing
// session with a small amount of files.
// this.sleep(300);
if (it.hasNext()
{
if (threadCount <> 8)
{
// invoke new worker thread on the next document
worker = new Worker(workerThreads, "work", it.next());
worker.start();
}
}
else
{
//no more files, we can leave
break;
}
threadCount = workerThreads.enumerate(threadEnum);
}
// wait until all threads are finished
threadCount = workerThreads.enumerate(threadEnum);
for (Thread thread : threadEnum)
{
if (thread != null)
{
thread.join();
}
}
This is a very easy way to use the capabilities of threading to process the files faster. Come back for Threading for Performance II and I will discuss how to report on the threaded process to subsequent requests against the servlet.
Labels:
enterprise_software,
java,
threads
Tuesday, January 6, 2009
Integrity Checking of Keystores
Recently I had to write functionality to rekey the encrypted documents in an application. When the new keystore is uploaded I ran into the question of determining if it was valid. After a bit of searching I found that attempting to load a keystore will throw an error if there is any thing wrong with the keystore format.
Unfortunately this goes against my rule for using errors to discriminate bad inputs. But for me to do the research and build some sort of keystore validator would be a waste... So we do this.
// the load function checks the integrity of the keystore.
try
{
keyStore.load(fis, password1.toCharArray());
}
catch (IOException ioe)
{
log.error("Not a valid keystore. " + ioe.getMessage());
request.setAttribute("errorMessage", ioe.getMessage());
this.forwardToTemplate(request, response, adminTemplate);
return;
}
Unfortunately this goes against my rule for using errors to discriminate bad inputs. But for me to do the research and build some sort of keystore validator would be a waste... So we do this.
Subscribe to:
Posts (Atom)