encryption boot camp on the jvm
DESCRIPTION
Does your application transmit customer information? Are there fields of sensitive customer data stored in your DB? Can your application be used on insecure networks? If so, you need a working knowledge of encryption and how to leverage Open Source APIs and libraries to make securing your data as easy as possible. Encryption is quickly becoming a developer’s new frontier of responsibility in many data-centric applications.In today’s data-sensitive and news-sensationalizing world, don’t become the next headline by an inadvertent release of private customer or company data. Secure your persisted, transmitted and in-memory data and learn the terminology you’ll need to navigate the ecosystem of symmetric and public/private key encryption.TRANSCRIPT
ENCRYPTION BOOT CAMP
security is your mission
SECURITY ON THE JVMWhat’s your position?
ENCRYPTING?
statistics say probably not
WORRIED?You should be
Matthew McCullough
@matthewmccull
#EncryptBC
http://speakerrate.com/matthew.mccullough
ANCIENT HISTORYEverything old is new again
Plain
Sigh
t
Sensitive Data
Plain
Sigh
t
Recipient orStorage
Sensitive Data
Plain
Sigh
t
Recipient orStorage
Sensitive Data
Con
tent
s Obs
cure
d
“I’m all over
this new
encryption
stuff boss”
44 B.C.That’s 2,054 years ago...
Julius Caesar
Caesar Cipher
A B C D E F G
A B C D E F G
a.k.a. ROT(2) Shift Cipher
Caesar Cipher
A B C D E F G
A B C D E F G
a.k.a. ROT(2) Shift Cipher
Caesar Cipher
RotationInteger=
Rot(x)
Caesar Cipher
Z M S R
Caesar Cipher
Z M S RA N T S if encrypted with ROT(-1)
Caesar Cipher
Z M S RA N T S if encrypted with ROT(-1)
B O U T if encrypted with ROT(-2)
/** * A naively simple rotation cipher implementation. * USAGE: groovy RotateWord.groovy <yourword> */public class RotateWord { /** * Rotate one character by the specified amount */ private static char rotateChar(char c, int rotationAmount) { //a == 97, z == 122 int num = (int)c int rotated = num + rotationAmount int adjusted //Handle roll-around wrapping if (rotated > 122) adjusted = rotated - 26 else if (rotated < 97) adjusted = rotated + 26 else adjusted = rotated char adjustedChar = (char)adjusted return adjustedChar } /** * Rotate the entire String by the specified rotation amount. */ public static String rotateAllChars(String plainText, int rotationAmount) { String encodedMessage = "" //Loop through each character in the plaintext for (int i = 0; i < plainText.length(); i++) { //TODO: Improve to handle upper and lower case letters char c = plainText.toLowerCase().charAt(i) encodedMessage += rotateChar(c, rotationAmount) } return encodedMessage } public static void main (String[] args) { String originalword = args[0] println "Rot(-3) Word: " + rotateAllChars(originalword, -3) println "Rot(-2) Word: " + rotateAllChars(originalword, -2) println "Rot(-1) Word: " + rotateAllChars(originalword, -1) println "Original Word: ${originalword}" println "Rot(1) Word: " + rotateAllChars(originalword, 1) println "Rot(2) Word: " + rotateAllChars(originalword, 2) println "Rot(3) Word: " + rotateAllChars(originalword, 3) println "Rot(4) Word: " + rotateAllChars(originalword, 4) println "Rot(5) Word: " + rotateAllChars(originalword, 5) println "Rot(6) Word: " + rotateAllChars(originalword, 6) println "Rot(7) Word: " + rotateAllChars(originalword, 7) }}
/** * A naively simple rotation cipher implementation. * USAGE: groovy RotateWord.groovy <yourword> */public class RotateWord { /** * Rotate one character by the specified amount */ private static char rotateChar(char c, int rotationAmount) { //a == 97, z == 122 int num = (int)c int rotated = num + rotationAmount int adjusted //Handle roll-around wrapping if (rotated > 122) adjusted = rotated - 26 else if (rotated < 97) adjusted = rotated + 26 else adjusted = rotated char adjustedChar = (char)adjusted return adjustedChar } /** * Rotate the entire String by the specified rotation amount. */ public static String rotateAllChars(String plainText, int rotationAmount) { String encodedMessage = "" //Loop through each character in the plaintext for (int i = 0; i < plainText.length(); i++) { //TODO: Improve to handle upper and lower case letters char c = plainText.toLowerCase().charAt(i) encodedMessage += rotateChar(c, rotationAmount) } return encodedMessage } public static void main (String[] args) { String originalword = args[0] println "Rot(-3) Word: " + rotateAllChars(originalword, -3) println "Rot(-2) Word: " + rotateAllChars(originalword, -2) println "Rot(-1) Word: " + rotateAllChars(originalword, -1) println "Original Word: ${originalword}" println "Rot(1) Word: " + rotateAllChars(originalword, 1) println "Rot(2) Word: " + rotateAllChars(originalword, 2) println "Rot(3) Word: " + rotateAllChars(originalword, 3) println "Rot(4) Word: " + rotateAllChars(originalword, 4) println "Rot(5) Word: " + rotateAllChars(originalword, 5) println "Rot(6) Word: " + rotateAllChars(originalword, 6) println "Rot(7) Word: " + rotateAllChars(originalword, 7) }}
/** * A naively simple rotation cipher implementation. * USAGE: groovy RotateWord.groovy <yourword> */public class RotateWord { /** * Rotate one character by the specified amount */ private static char rotateChar(char c, int rotationAmount) { //a == 97, z == 122 int num = (int)c int rotated = num + rotationAmount int adjusted //Handle roll-around wrapping if (rotated > 122) adjusted = rotated - 26 else if (rotated < 97) adjusted = rotated + 26 else adjusted = rotated char adjustedChar = (char)adjusted return adjustedChar } /** * Rotate the entire String by the specified rotation amount. */ public static String rotateAllChars(String plainText, int rotationAmount) { String encodedMessage = "" //Loop through each character in the plaintext for (int i = 0; i < plainText.length(); i++) { //TODO: Improve to handle upper and lower case letters char c = plainText.toLowerCase().charAt(i) encodedMessage += rotateChar(c, rotationAmount) } return encodedMessage } public static void main (String[] args) { String originalword = args[0] println "Rot(-3) Word: " + rotateAllChars(originalword, -3) println "Rot(-2) Word: " + rotateAllChars(originalword, -2) println "Rot(-1) Word: " + rotateAllChars(originalword, -1) println "Original Word: ${originalword}" println "Rot(1) Word: " + rotateAllChars(originalword, 1) println "Rot(2) Word: " + rotateAllChars(originalword, 2) println "Rot(3) Word: " + rotateAllChars(originalword, 3) println "Rot(4) Word: " + rotateAllChars(originalword, 4) println "Rot(5) Word: " + rotateAllChars(originalword, 5) println "Rot(6) Word: " + rotateAllChars(originalword, 6) println "Rot(7) Word: " + rotateAllChars(originalword, 7) }}
/** * A naively simple rotation cipher implementation. * USAGE: groovy RotateWord.groovy <yourword> */public class RotateWord { /** * Rotate one character by the specified amount */ private static char rotateChar(char c, int rotationAmount) { //a == 97, z == 122 int num = (int)c int rotated = num + rotationAmount int adjusted //Handle roll-around wrapping if (rotated > 122) adjusted = rotated - 26 else if (rotated < 97) adjusted = rotated + 26 else adjusted = rotated char adjustedChar = (char)adjusted return adjustedChar } /** * Rotate the entire String by the specified rotation amount. */ public static String rotateAllChars(String plainText, int rotationAmount) { String encodedMessage = "" //Loop through each character in the plaintext for (int i = 0; i < plainText.length(); i++) { //TODO: Improve to handle upper and lower case letters char c = plainText.toLowerCase().charAt(i) encodedMessage += rotateChar(c, rotationAmount) } return encodedMessage } public static void main (String[] args) { String originalword = args[0] println "Rot(-3) Word: " + rotateAllChars(originalword, -3) println "Rot(-2) Word: " + rotateAllChars(originalword, -2) println "Rot(-1) Word: " + rotateAllChars(originalword, -1) println "Original Word: ${originalword}" println "Rot(1) Word: " + rotateAllChars(originalword, 1) println "Rot(2) Word: " + rotateAllChars(originalword, 2) println "Rot(3) Word: " + rotateAllChars(originalword, 3) println "Rot(4) Word: " + rotateAllChars(originalword, 4) println "Rot(5) Word: " + rotateAllChars(originalword, 5) println "Rot(6) Word: " + rotateAllChars(originalword, 6) println "Rot(7) Word: " + rotateAllChars(originalword, 7) }}
/** * A naively simple rotation cipher implementation. * USAGE: groovy RotateWord.groovy <yourword> */public class RotateWord { /** * Rotate one character by the specified amount */ private static char rotateChar(char c, int rotationAmount) { //a == 97, z == 122 int num = (int)c int rotated = num + rotationAmount int adjusted //Handle roll-around wrapping if (rotated > 122) adjusted = rotated - 26 else if (rotated < 97) adjusted = rotated + 26 else adjusted = rotated char adjustedChar = (char)adjusted return adjustedChar } /** * Rotate the entire String by the specified rotation amount. */ public static String rotateAllChars(String plainText, int rotationAmount) { String encodedMessage = "" //Loop through each character in the plaintext for (int i = 0; i < plainText.length(); i++) { //TODO: Improve to handle upper and lower case letters char c = plainText.toLowerCase().charAt(i) encodedMessage += rotateChar(c, rotationAmount) } return encodedMessage } public static void main (String[] args) { String originalword = args[0] println "Rot(-3) Word: " + rotateAllChars(originalword, -3) println "Rot(-2) Word: " + rotateAllChars(originalword, -2) println "Rot(-1) Word: " + rotateAllChars(originalword, -1) println "Original Word: ${originalword}" println "Rot(1) Word: " + rotateAllChars(originalword, 1) println "Rot(2) Word: " + rotateAllChars(originalword, 2) println "Rot(3) Word: " + rotateAllChars(originalword, 3) println "Rot(4) Word: " + rotateAllChars(originalword, 4) println "Rot(5) Word: " + rotateAllChars(originalword, 5) println "Rot(6) Word: " + rotateAllChars(originalword, 6) println "Rot(7) Word: " + rotateAllChars(originalword, 7) }}
/** * A naively simple rotation cipher implementation. * USAGE: groovy RotateWord.groovy <yourword> */public class RotateWord { /** * Rotate one character by the specified amount */ private static char rotateChar(char c, int rotationAmount) { //a == 97, z == 122 int num = (int)c int rotated = num + rotationAmount int adjusted //Handle roll-around wrapping if (rotated > 122) adjusted = rotated - 26 else if (rotated < 97) adjusted = rotated + 26 else adjusted = rotated char adjustedChar = (char)adjusted return adjustedChar } /** * Rotate the entire String by the specified rotation amount. */ public static String rotateAllChars(String plainText, int rotationAmount) { String encodedMessage = "" //Loop through each character in the plaintext for (int i = 0; i < plainText.length(); i++) { //TODO: Improve to handle upper and lower case letters char c = plainText.toLowerCase().charAt(i) encodedMessage += rotateChar(c, rotationAmount) } return encodedMessage } public static void main (String[] args) { String originalword = args[0] println "Rot(-3) Word: " + rotateAllChars(originalword, -3) println "Rot(-2) Word: " + rotateAllChars(originalword, -2) println "Rot(-1) Word: " + rotateAllChars(originalword, -1) println "Original Word: ${originalword}" println "Rot(1) Word: " + rotateAllChars(originalword, 1) println "Rot(2) Word: " + rotateAllChars(originalword, 2) println "Rot(3) Word: " + rotateAllChars(originalword, 3) println "Rot(4) Word: " + rotateAllChars(originalword, 4) println "Rot(5) Word: " + rotateAllChars(originalword, 5) println "Rot(6) Word: " + rotateAllChars(originalword, 6) println "Rot(7) Word: " + rotateAllChars(originalword, 7) }}
/** * A naively simple rotation cipher implementation. * USAGE: groovy RotateWord.groovy <yourword> */public class RotateWord { /** * Rotate one character by the specified amount */ private static char rotateChar(char c, int rotationAmount) { //a == 97, z == 122 int num = (int)c int rotated = num + rotationAmount int adjusted //Handle roll-around wrapping if (rotated > 122) adjusted = rotated - 26 else if (rotated < 97) adjusted = rotated + 26 else adjusted = rotated char adjustedChar = (char)adjusted return adjustedChar } /** * Rotate the entire String by the specified rotation amount. */ public static String rotateAllChars(String plainText, int rotationAmount) { String encodedMessage = "" //Loop through each character in the plaintext for (int i = 0; i < plainText.length(); i++) { //TODO: Improve to handle upper and lower case letters char c = plainText.toLowerCase().charAt(i) encodedMessage += rotateChar(c, rotationAmount) } return encodedMessage } public static void main (String[] args) { String originalword = args[0] println "Rot(-3) Word: " + rotateAllChars(originalword, -3) println "Rot(-2) Word: " + rotateAllChars(originalword, -2) println "Rot(-1) Word: " + rotateAllChars(originalword, -1) println "Original Word: ${originalword}" println "Rot(1) Word: " + rotateAllChars(originalword, 1) println "Rot(2) Word: " + rotateAllChars(originalword, 2) println "Rot(3) Word: " + rotateAllChars(originalword, 3) println "Rot(4) Word: " + rotateAllChars(originalword, 4) println "Rot(5) Word: " + rotateAllChars(originalword, 5) println "Rot(6) Word: " + rotateAllChars(originalword, 6) println "Rot(7) Word: " + rotateAllChars(originalword, 7) }}
> groovy RotateWord.groovy ants
Rot(-3) Word: xkqpRot(-2) Word: ylrq
Rot(2) Word: cpvuRot(3) Word: dqwv
Rot(-1) Word: zmsr
Original Word: ants
Rot(1) Word: bout
> groovy RotateWord.groovy ants
Rot(-3) Word: xkqpRot(-2) Word: ylrq
Rot(2) Word: cpvuRot(3) Word: dqwv
Rot(-1) Word: zmsr
Original Word: ants
Rot(1) Word: bout
BROKENPerfectly safe data is a myth
Compromised
! Every algorithm is vulnerable
! crack by brute force
! Crack by rainbow tables
! Function of time + money + hardware
$2000
$500
Which would you hit?
$10,000
$50
Now which would you hit?
JCE PRIMERThe world of Java crypto
Java Cryptography Extension
★ known as JCE
Java Cryptography Extension
★ known as JCE
★ included in all JREs Since Java 1.2
Java Cryptography Extension
★ known as JCE
★ included in all JREs Since Java 1.2
★ Pluggable provider architecture
Java Cryptography Extension
★ known as JCE
★ included in all JREs Since Java 1.2
★ Pluggable provider architecture
★ JCE extends Java Cryptography Architecture (JCA)
JCE Providers
! Default Sun JRE providers! SUN! SunJCE! SunJSSE! SunRsaSign
! Bouncycastle provider! Adds AES capabilities
Registering a Provider
! Static! <java-home>/lib/security/java.security! security.provider.n=masterClassName
Registering a Provider
! Dynamic! java.security.Security class
! addProvider()! insertProviderAt()
! not persistent across VM instances
EnCryption & the Law
country borders stop bits
JCE Strength
!Jurisdiction Policy Files! “Strong”! “Unlimited”
JCE Strength
! Strong strength included in all JREs
! Unlimited strength is a separate download available based on US export rules
Worldwide Policy
// File: default_local.policy// Some countries have import limits on crypto strength.// This policy file is worldwide importable.grant { permission javax.crypto.CryptoPermission "DES", 64; permission javax.crypto.CryptoPermission "DESede", *; permission javax.crypto.CryptoPermission "RC2", 128, "javax.crypto.spec.RC2ParameterSpec", 128; permission javax.crypto.CryptoPermission "RC4", 128; permission javax.crypto.CryptoPermission "RC5", 128, "javax.crypto.spec.RC5ParameterSpec", *, 12, *; permission javax.crypto.CryptoPermission "RSA", 2048; permission javax.crypto.CryptoPermission *, 128;};
Max Key Sizes
Algorithm Max Key Size
DES 64
DESede3des
168
RC2 128
RC4 128
RC5 128
RSA 2048
Others 128
Key Size & Security
Symmetric Key Size
160 bit DES
Key Size & Security
Symmetric Key Size
Asymmetric Key Size
1024 bit RSA
160 bit DES
Key Size & Security
Symmetric Key Size
Asymmetric Key Size
Security
1024 bit RSA
112 bits
160 bit DES
Key Size & Security
Symmetric Key Size
Asymmetric Key Size
Security Security
1024 bit RSA
112 bits
160 bit DES
128 bits
Random Numbers
Seed the machine
SecureRandom
! java.security.SecureRandom
! Cryptographically strong random number generator (RNG)
! “Unable to distinguish from a true random source”
package com.ambientideas;
import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SecureRandomNumber { public static void main( String[] args ) throws NoSuchAlgorithmException { //Do the expensive one time setup of the // random number generator instance SecureRandom prng = SecureRandom.getInstance("SHA1PRNG"); //Get the next random number String randomNum = new Integer( prng.nextInt() ).toString(); System.out.println("Random number: " + randomNum); }}
package com.ambientideas;
import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SecureRandomNumber { public static void main( String[] args ) throws NoSuchAlgorithmException { //Do the expensive one time setup of the // random number generator instance SecureRandom prng = SecureRandom.getInstance("SHA1PRNG"); //Get the next random number String randomNum = new Integer( prng.nextInt() ).toString(); System.out.println("Random number: " + randomNum); }}
package com.ambientideas;
import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SecureRandomNumber { public static void main( String[] args ) throws NoSuchAlgorithmException { //Do the expensive one time setup of the // random number generator instance SecureRandom prng = SecureRandom.getInstance("SHA1PRNG"); //Get the next random number String randomNum = new Integer( prng.nextInt() ).toString(); System.out.println("Random number: " + randomNum); }}
Result
Random number: 1633471380
Digests & HashesOne way functions
What is a Digest?
! Small set of bytes representing a large message
! Small change in message = large change in digest
! Integrity check for large data
! Password storage mechanism
MessageDigest
! java.security.MessageDigest
! Multiple algorithms available! MD5 (128 bit)! SHA-1 (160 bit)
MessageDigest
!MD5! U. S. Department of Homeland
Security said MD5"considered cryptographically broken and unsuitable for further use"
http://xkcd.com/538/
import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;
/** * Digest a string message via SHA1. * * Demonstrate that very similar messages * have radically different hashes. */public class MessageDigestSHA { public static void main( String[] args ) throws NoSuchAlgorithmException { //Set up the message to be encoded String message1 = "Four score and seven years ago"; String message2 = "Four score and seven tears ago"; System.out.println("Message1 SHA1 digest: " + shaAndBase64Encode(message1)); System.out.println("Message2 SHA1 digest: " + shaAndBase64Encode(message2)); } /** * Helper function to both SHA-1 hash and * base64 encode the resulting bytes to a String */ public static String shaAndBase64Encode(String message) throws NoSuchAlgorithmException { MessageDigest sha = MessageDigest.getInstance("SHA-1"); //Salt could be applied here //Integer salt = <some random number generator> //sha.update(salt.getBytes()); byte[] digest = sha.digest(message.getBytes()); return new sun.misc.BASE64Encoder().encode(digest); }}
import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;
/** * Digest a string message via SHA1. * * Demonstrate that very similar messages * have radically different hashes. */public class MessageDigestSHA { public static void main( String[] args ) throws NoSuchAlgorithmException { //Set up the message to be encoded String message1 = "Four score and seven years ago"; String message2 = "Four score and seven tears ago"; System.out.println("Message1 SHA1 digest: " + shaAndBase64Encode(message1)); System.out.println("Message2 SHA1 digest: " + shaAndBase64Encode(message2)); } /** * Helper function to both SHA-1 hash and * base64 encode the resulting bytes to a String */ public static String shaAndBase64Encode(String message) throws NoSuchAlgorithmException { MessageDigest sha = MessageDigest.getInstance("SHA-1"); //Salt could be applied here //Integer salt = <some random number generator> //sha.update(salt.getBytes()); byte[] digest = sha.digest(message.getBytes()); return new sun.misc.BASE64Encoder().encode(digest); }}
Input
Message1 SHA1 digest: DmCJIg4Bq/xpGIxVXxo3IB0vo38=Message2 SHA1 digest: oaLHt8tr31ttngCDjyYuWowF5Mc=
String message1 = "Four score and seven years ago";String message2 = "Four score and seven tears ago";
Result
JDK KeytoolKey generation, storage & management
Keytool
! Creates! Keystore! Truststore
! Functions! -genkey! -list! -import! -export! -certreq
Creating a keystore
keytool -genkeypair -keyalg RSA -keysize 2048 -keystore myapp.keystore
Enter keystore password: ********Re-enter new password: ********
What is your first and last name? [Unknown]: Matthew McCulloughWhat is the name of your organizational unit? [Unknown]: Consulting What is the name of your organization? [Unknown]: Ambient Ideas, LLCWhat is the name of your City or Locality? [Unknown]: DenverWhat is the name of your State or Province? [Unknown]: ColoradoWhat is the two-letter country code for this unit? [Unknown]: US
Is CN=Matthew McCullough, OU=Consulting, O="Ambient Ideas, LLC", L=Denver, ST=Colorado, C=US correct? [no]: yes
Enter key password for <mykey>! (RETURN if same as keystore password):
Creating a keystorekeytool -genkeypair -keyalg RSA -keysize 2048 -keystore myapp.keystore
Enter keystore password: ********Re-enter new password: ********
What is your first and last name? [Unknown]: Matthew McCulloughWhat is the name of your organizational unit? [Unknown]: Consulting What is the name of your organization? [Unknown]: Ambient Ideas, LLCWhat is the name of your City or Locality? [Unknown]: DenverWhat is the name of your State or Province? [Unknown]: ColoradoWhat is the two-letter country code for this unit? [Unknown]: US
Is CN=Matthew McCullough, OU=Consulting, O="Ambient Ideas, LLC", L=Denver, ST=Colorado, C=US correct? [no]: yes
Enter key password for <mykey>! (RETURN if same as keystore password):
Using a keystore
java -Djavax.net.ssl.keyStore=keystore \ -Djavax.net.ssl.keyStorePassword=y3$1t1s \ ServerApp
Using a Truststore
java -Djavax.net.ssl.trustStore=truststore \ -Djavax.net.ssl.trustStorePassword=tru$tM3 \ ClientApp
JSSENetwork communications security
JSSE
! Java Secure Socket Extension
! Built on top of JCE
! Specific to networking
! Standard as of JRE 1.4
! Implementations of! Secure Sockets Layer (SSL) 2.0 and 3.0! Transport Layer Security (TLS) 1.0
JAASAuthentication and Authorization
JAAS
! Java Authentication and Authorization Service
! Single sign on helper
! Supports biometric, smartcard devices
! Adds “user” control(above code control)
SYMMETRICMy key is your key
Why Symmetric?
! Fast
! Bulk data
! Controlled environment
! Never decrypted at remote end
Symmetric Problems
! Keys vulnerable to capture
Symmetric Problems
! Keys vulnerable to capture
! Eavesdropping on future communications after key compromise
! Key distribution challenges
! Triangular number key growth
Symmetric Problems! Triangular number key growth
DES & 3DES
! Block cipher
! DES is known to be broken
! 3DES and DESede
! basically three passes of DES
! Reasonably strong
Blowfish
! Secure replacement for DES
! Faster than DES
! Block cipher
RC4
! Rivest’s code 4
! Stream cipher
AES
! Advanced Encryption Standard
! Government standard! Rijndael algorithm
(Joan Daemen, Vincent Rijmen)! 4 years of evaluation! Final in December 2000
! Very Secure
! block cipher
import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SymmetricEncrypt { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; //Build a new encryption key final KeyGenerator keyGen = KeyGenerator.getInstance("DESede"); keyGen.init(168); final SecretKey desKey = keyGen.generateKey(); //Set up the cipher final Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); ////////////////////////////////////// //Put the cipher in encryption mode desCipher.init(Cipher.ENCRYPT_MODE, desKey); //Encrypt and output the base64 data byte[] clearText = message1.getBytes(); byte[] encryptedBytes = desCipher.doFinal(clearText); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); ////////////////////////////////////// //Put the cipher in decryption mode desCipher.init(Cipher.DECRYPT_MODE, desKey); //Decrypt and output the original string byte[] decryptedBytes = desCipher.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SymmetricEncrypt { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; //Build a new encryption key final KeyGenerator keyGen = KeyGenerator.getInstance("DESede"); keyGen.init(168); final SecretKey desKey = keyGen.generateKey(); //Set up the cipher final Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); ////////////////////////////////////// //Put the cipher in encryption mode desCipher.init(Cipher.ENCRYPT_MODE, desKey); //Encrypt and output the base64 data byte[] clearText = message1.getBytes(); byte[] encryptedBytes = desCipher.doFinal(clearText); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); ////////////////////////////////////// //Put the cipher in decryption mode desCipher.init(Cipher.DECRYPT_MODE, desKey); //Decrypt and output the original string byte[] decryptedBytes = desCipher.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SymmetricEncrypt { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; //Build a new encryption key final KeyGenerator keyGen = KeyGenerator.getInstance("DESede"); keyGen.init(168); final SecretKey desKey = keyGen.generateKey(); //Set up the cipher final Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); ////////////////////////////////////// //Put the cipher in encryption mode desCipher.init(Cipher.ENCRYPT_MODE, desKey); //Encrypt and output the base64 data byte[] clearText = message1.getBytes(); byte[] encryptedBytes = desCipher.doFinal(clearText); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); ////////////////////////////////////// //Put the cipher in decryption mode desCipher.init(Cipher.DECRYPT_MODE, desKey); //Decrypt and output the original string byte[] decryptedBytes = desCipher.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SymmetricEncrypt { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; //Build a new encryption key final KeyGenerator keyGen = KeyGenerator.getInstance("DESede"); keyGen.init(168); final SecretKey desKey = keyGen.generateKey(); //Set up the cipher final Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); ////////////////////////////////////// //Put the cipher in encryption mode desCipher.init(Cipher.ENCRYPT_MODE, desKey); //Encrypt and output the base64 data byte[] clearText = message1.getBytes(); byte[] encryptedBytes = desCipher.doFinal(clearText); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); ////////////////////////////////////// //Put the cipher in decryption mode desCipher.init(Cipher.DECRYPT_MODE, desKey); //Decrypt and output the original string byte[] decryptedBytes = desCipher.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
Input
Encrypted text: P0FT6N3XXrohtsz7OLh3FGYY0wErkPIur1DP6Csbj4g=Decrypted text: Four score and seven years ago
String message1 = "Four score and seven years ago";
Result
Encrypted isn’t enough?
http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
ASYMMETRICThrowing away keys
faster than an intern locksmith
Diffie-Hellman
! Key Agreement Protocol
! Alice & Bob independently generate the shared (session) key
! asymmetric Key handshake
! 1970s
! Vulnerable to MITM attack! Fixed by
! PKI! signing the agreed key
DH Diagrammed
RSA
! Ron Rivest, Adi Shamir, Leonard Adleman
! Published in 1978
! M.I.T. Patented in 1983
! Patent Expired in 2000
import java.io.IOException;import java.security.InvalidKeyException;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class EncryptRSA { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; // Generate the Key Pair final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); final SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); keyGen.initialize(1024, random); KeyPair pair = keyGen.generateKeyPair(); final PrivateKey privKey = pair.getPrivate(); final PublicKey pubKey = pair.getPublic(); //Encrypt using the private key Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsa.init(Cipher.ENCRYPT_MODE, privKey); byte[] encryptedBytes = rsa.doFinal(message1.getBytes()); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); //Decrypt using the private key rsa.init(Cipher.DECRYPT_MODE, pubKey); byte[] decryptedBytes = rsa.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
import java.io.IOException;import java.security.InvalidKeyException;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class EncryptRSA { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; // Generate the Key Pair final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); final SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); keyGen.initialize(1024, random); KeyPair pair = keyGen.generateKeyPair(); final PrivateKey privKey = pair.getPrivate(); final PublicKey pubKey = pair.getPublic(); //Encrypt using the private key Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsa.init(Cipher.ENCRYPT_MODE, privKey); byte[] encryptedBytes = rsa.doFinal(message1.getBytes()); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); //Decrypt using the private key rsa.init(Cipher.DECRYPT_MODE, pubKey); byte[] decryptedBytes = rsa.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
import java.io.IOException;import java.security.InvalidKeyException;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class EncryptRSA { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; // Generate the Key Pair final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); final SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); keyGen.initialize(1024, random); KeyPair pair = keyGen.generateKeyPair(); final PrivateKey privKey = pair.getPrivate(); final PublicKey pubKey = pair.getPublic(); //Encrypt using the private key Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsa.init(Cipher.ENCRYPT_MODE, privKey); byte[] encryptedBytes = rsa.doFinal(message1.getBytes()); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); //Decrypt using the private key rsa.init(Cipher.DECRYPT_MODE, pubKey); byte[] decryptedBytes = rsa.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
import java.io.IOException;import java.security.InvalidKeyException;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class EncryptRSA { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; // Generate the Key Pair final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); final SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); keyGen.initialize(1024, random); KeyPair pair = keyGen.generateKeyPair(); final PrivateKey privKey = pair.getPrivate(); final PublicKey pubKey = pair.getPublic(); //Encrypt using the private key Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsa.init(Cipher.ENCRYPT_MODE, privKey); byte[] encryptedBytes = rsa.doFinal(message1.getBytes()); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); //Decrypt using the private key rsa.init(Cipher.DECRYPT_MODE, pubKey); byte[] decryptedBytes = rsa.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
Input
Encrypted text: A8Is+4r7sDn28fD6IQvZiR5JxPs/vh7UnXrF38acJt6R/ARisj/zLtC7Xn6iJgNQPhc16wkVZhCFem7oNoim+ooTUDDZQ+E3qP6y/DZJGkLBoZuZVLeLAW1LUtHSzduRUOg1uMynJz14wxzwfV8wfRwfatpySkOhGqWS63bPNRs=Decrypted text: Four score and seven years ago
String message1 = "Four score and seven years ago";
Result
OTHER FRAMEWORKSand alternative JCE providers
Bouncy Castle
! JCE Provider
! Many more encryption and digest algorithms than the Sun provider (AES)
Jasypt
JasyptFrictionless Java encryption
Gnu
GnuOpen source library
WIFIYou are the weakest link
WIFI Algorithms
!WEP
WIFI Algorithms
!WEP
!WPA
WIFI Algorithms
!WEP
!WPA
!WPA2
WIFI Algorithms
TKIP
!WEP
!WPA
!WPA2AES
WIFI Algorithms
TKIP
!WEP
!WPA
!WPA2 AES
TJ Maxx
TJ Maxx
! $1 billon USD final cost
! 45 million credit card numbers stolen
“
”
Many security experts have criticized the
strength of WEP encryption. WEP was initially
cracked in 2001, and most recently broken by
German researchers last month
using an ordinary
laptop in under three
seconds— Tom Espiner, ZDNet UK
WIFI Interception
! Hey Look! A MyFreeWIFI SSID...
! Tempting
! Ridiculously unsafe
Tools of the Trade
!AirCrack!AirSnort!WireShark!Silent Proxies
WEP Cracking
! Listen for packets! Slow! Untraceable
! Inject bad packets! Listen for reply! Faster
! leaves a footprint
WireShark Demo
Upside-Down-TernetDemo
PRINTED MATERIALSDead tree propagation of security
1997
1998 Java 1.1 & 1.2
2004 Java 1.4
2005 Java 5
2008
ENCRYPTION BOOT CAMPsecurity mission completed
ENCRYPTION BOOT CAMPsecurity mission completed
@matthewmccull
#EncryptBC
http://ambientideas.com/blog
http://speakerrate.com/matthew.mccullough
REFERENCES
! Sun docs! http://java.sun.com/javase/6/docs/technotes/
guides/security/crypto/CryptoSpec.html! http://java.sun.com/javase/technologies/security/! http://java.sun.com/javase/6/docs/technotes/
guides/security/jsse/JSSERefGuide.html! http://java.sun.com/javase/6/docs/api/java/
security/Security.html
! BouncyCastle JCE Provider! http://www.bouncycastle.org/documentation.html
References
! Sample Code! http://github.com/matthewmccullough/
encryption-jvm-bootcamp
! Miscellaneous! http://www.ietf.org/rfc/rfc3852.txt! http://en.wikipedia.org/wiki/
Abstract_Syntax_Notation_One
References
! CMS! Cryptographic Message Syntax (CMS)
objects! RFC 3852! PKCS#7 (formerly RFC 2630, 3369)! http://www.ietf.org/rfc/rfc3852.txt
! ASN.1! Abstract Syntax Notation One! 1984 X.409, 1988 X.208, 1995 X.680,
2002! http://www.asn1.org/
Acronyms
CREDITS
! http://www.ambientideasphotography.com! http://stockfootageforfree.com/! http://xkcd.com/538/! http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation! http://matdonline.free.fr/RSA-Diffie-Hellman-explained-in-5-
minutes.htm! http://www.isg.rhul.ac.uk/node/329! http://www.isg.rhul.ac.uk/files/IMG_9819.JPG! http://www.usc.edu/dept/molecular-science/pictures/RSA-2003.jpg! All others, iStockPhoto.com
Outtakes
Steganography
! Data in pictures! Not necessarily encrypted! Merely hidden in pedestrian files
Steganography
! MP3! JPEG! DIVX! TCP Retry Packets! Email Headers
Steganography
! High signal to noise ratio! Slow but
! Inconspicuous
Cracks in the News
! Thomas Jefferson letter! London Tube Oyster cards! GSM! Iraq drone video feeds! Pacemakers! Zune! WPA! Blue-ray! DVD! Skype! Windows Vista BitLocker
Encryption & The Law
!Encryption considered a munition under international law
!1999 Relaxation of rules
Digital Signatures
! Hash with Private Key
! Public Private Key Systems
! Public Key Infrastructure (PKI)
Breakthroughs
! IBM! Statistics on encrypted data
! No compromise on security or anonymity
Keys
! Clickers/Tokens
! One Time Pads (paper)
! Message Digests == Hash?! Certificates (x509 v3)! Digital signatures
! Just means hashing a message, then signing the hash with the private key
! Later verified by decrypting the hash with the public key, then re-running the hash and comparing the two hashes.
! Block vs Stream ciphers
Misc
Cryptographic Message Syntax
Sign / Digest / Auth / Encrypt
Cryptographic Message Syntax
Session Keys
! symmetric key exchanged securely by a private/public key initial transaction
Elliptic Curve
! Faster than standard public key encryption
! ECC
! Based on elliptic curve logarithm problem
ENCRYPTION BOOT CAMP
security is your mission
© Matthew McCullough, Ambient Ideas, LLC
1Friday, January 15, 2010
SECURITY ON THE JVMWhat’s your position?
2Friday, January 15, 2010
HACK ATTEMPTS PER DAY>3 0 0 , 0 0 0
3Friday, January 15, 2010
ENCRYPTING?
statistics say probably not
4Friday, January 15, 2010
WORRIED?You should be
5Friday, January 15, 2010
Matthew McCullough
@matthewmccull
#EncryptBC
http://speakerrate.com/matthew.mccullough
6Friday, January 15, 2010
ANCIENT HISTORYEverything old is new again
7Friday, January 15, 2010
Plain
Sigh
t
Recipient orStorage
Sensitive Data
Con
tent
s Obs
cure
d
Craziest idea ever! Everyone knows you need to keep secret information hidden in a body cavity and physically transport it to the recipient. All the movies do that.
8Friday, January 15, 2010
“I’m all over
this new
encryption
stuff boss”
Even though we make minor adjustments, they are often seeded by our predecessors.Even encryption is over old with a fresh coat of paint
9Friday, January 15, 2010
44 B.C.That’s 2,054 years ago...
10Friday, January 15, 2010
Julius Caesar
And even the Egyptians before him were trying math for encryption.http://www.amazon.com/Code-Book-Science-Secrecy-Cryptography/dp/0385495323/ref=sr_1_7?ie=UTF8&s=books&qid=1263535206&sr=8-7
11Friday, January 15, 2010
Caesar Cipher
A B C D E F G
A B C D E F G
a.k.a. ROT(2) Shift Cipher
12Friday, January 15, 2010
Caesar Cipher
RotationInteger=
Rot(x)
13Friday, January 15, 2010
Caesar Cipher
Z M S R
30s 25s 20s 15s 10s 5s Stop
A N T S if encrypted with ROT(-1)
B O U T if encrypted with ROT(-2)
Encrypted Word
This is not an eye test at your optometristEnglish dictionary attack would be a good approach.ANTS and BOUT are solutions [ROT(+1) and ROT(+2)]
14Friday, January 15, 2010
/** * A naively simple rotation cipher implementation. * USAGE: groovy RotateWord.groovy <yourword> */public class RotateWord { /** * Rotate one character by the specified amount */ private static char rotateChar(char c, int rotationAmount) { //a == 97, z == 122 int num = (int)c int rotated = num + rotationAmount int adjusted //Handle roll-around wrapping if (rotated > 122) adjusted = rotated - 26 else if (rotated < 97) adjusted = rotated + 26 else adjusted = rotated char adjustedChar = (char)adjusted return adjustedChar } /** * Rotate the entire String by the specified rotation amount. */ public static String rotateAllChars(String plainText, int rotationAmount) { String encodedMessage = "" //Loop through each character in the plaintext for (int i = 0; i < plainText.length(); i++) { //TODO: Improve to handle upper and lower case letters char c = plainText.toLowerCase().charAt(i) encodedMessage += rotateChar(c, rotationAmount) } return encodedMessage } public static void main (String[] args) { String originalword = args[0] println "Rot(-3) Word: " + rotateAllChars(originalword, -3) println "Rot(-2) Word: " + rotateAllChars(originalword, -2) println "Rot(-1) Word: " + rotateAllChars(originalword, -1) println "Original Word: ${originalword}" println "Rot(1) Word: " + rotateAllChars(originalword, 1) println "Rot(2) Word: " + rotateAllChars(originalword, 2) println "Rot(3) Word: " + rotateAllChars(originalword, 3) println "Rot(4) Word: " + rotateAllChars(originalword, 4) println "Rot(5) Word: " + rotateAllChars(originalword, 5) println "Rot(6) Word: " + rotateAllChars(originalword, 6) println "Rot(7) Word: " + rotateAllChars(originalword, 7) }}
Look at how much effort it is to write even the simplest cipher (Caesar) implementation ourselves.
15Friday, January 15, 2010
> groovy RotateWord.groovy ants
Rot(-3) Word: xkqpRot(-2) Word: ylrq
Rot(2) Word: cpvuRot(3) Word: dqwv
Rot(-1) Word: zmsr
Original Word: ants
Rot(1) Word: bout
Think about the combinatoric and steganographic possibilities.16Friday, January 15, 2010
BROKENPerfectly safe data is a myth
17Friday, January 15, 2010
Compromised
! Every algorithm is vulnerable
! crack by brute force
! Crack by rainbow tables
! Function of time + money + hardware
18Friday, January 15, 2010
$2000
$500
Which would you hit?
Go into a jewelry store.Two possible storage containers to hit. Your informant has told you how much is in each.4X as much in the safe as in the wooden box.
19Friday, January 15, 2010
$10,000
$50
Now which would you hit?
Now the jewelry box contains 1/200th what the safe does. Would you still hit the wooden box?
20Friday, January 15, 2010
JCE PRIMERThe world of Java crypto
21Friday, January 15, 2010
Java Cryptography Extension
★ known as JCE
★ included in all JREs Since Java 1.2
★ Pluggable provider architecture
★ JCE extends Java Cryptography Architecture (JCA)
22Friday, January 15, 2010
JCE Providers
! Default Sun JRE providers! SUN! SunJCE! SunJSSE! SunRsaSign
! Bouncycastle provider! Adds AES capabilities
23Friday, January 15, 2010
Registering a Provider
! Static! <java-home>/lib/security/java.security! security.provider.n=masterClassName
24Friday, January 15, 2010
Registering a Provider
! Dynamic! java.security.Security class
! addProvider()! insertProviderAt()
! not persistent across VM instances
Can only be done by "trusted" programs with the appropriate privilege25Friday, January 15, 2010
EnCryption & the Law
country borders stop bits
26Friday, January 15, 2010
JCE Strength
!Jurisdiction Policy Files! “Strong”! “Unlimited”
27Friday, January 15, 2010
JCE Strength
! Strong strength included in all JREs
! Unlimited strength is a separate download available based on US export rules
28Friday, January 15, 2010
29Friday, January 15, 2010
30Friday, January 15, 2010
Worldwide Policy
// File: default_local.policy// Some countries have import limits on crypto strength.// This policy file is worldwide importable.grant { permission javax.crypto.CryptoPermission "DES", 64; permission javax.crypto.CryptoPermission "DESede", *; permission javax.crypto.CryptoPermission "RC2", 128, "javax.crypto.spec.RC2ParameterSpec", 128; permission javax.crypto.CryptoPermission "RC4", 128; permission javax.crypto.CryptoPermission "RC5", 128, "javax.crypto.spec.RC5ParameterSpec", *, 12, *; permission javax.crypto.CryptoPermission "RSA", 2048; permission javax.crypto.CryptoPermission *, 128;};
31Friday, January 15, 2010
Max Key Sizes
Algorithm Max Key Size
DES 64
DESede3des
168
RC2 128
RC4 128
RC5 128
RSA 2048
Others 128
http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html#AppE
32Friday, January 15, 2010
Key Size & Security
Symmetric Key Size
Asymmetric Key Size
Security Security
1024 bit RSA
112 bits
160 bit DES
128 bits
Speed is 1000x slower on asymmetric33Friday, January 15, 2010
Random Numbers
Seed the machine
34Friday, January 15, 2010
SecureRandom
! java.security.SecureRandom
! Cryptographically strong random number generator (RNG)
! “Unable to distinguish from a true random source”
A cryptographically strong random number generator passes all statistical tests that run in polynomial time asymptotically. It will pass any statistical test for randomness that does not require an exponentially increasing to infinite amount of time to run. All such polynomial time statistical tests will be unable to distinguish the random number generator from a true random source.http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#Conceptshttp://java.sun.com/javase/6/docs/api/java/security/SecureRandom.htmlhttp://java.sun.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA
35Friday, January 15, 2010
package com.ambientideas;
import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SecureRandomNumber { public static void main( String[] args ) throws NoSuchAlgorithmException { //Do the expensive one time setup of the // random number generator instance SecureRandom prng = SecureRandom.getInstance("SHA1PRNG"); //Get the next random number String randomNum = new Integer( prng.nextInt() ).toString(); System.out.println("Random number: " + randomNum); }}
36Friday, January 15, 2010
package com.ambientideas;
import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SecureRandomNumber { public static void main( String[] args ) throws NoSuchAlgorithmException { //Do the expensive one time setup of the // random number generator instance SecureRandom prng = SecureRandom.getInstance("SHA1PRNG"); //Get the next random number String randomNum = new Integer( prng.nextInt() ).toString(); System.out.println("Random number: " + randomNum); }}
37Friday, January 15, 2010
package com.ambientideas;
import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SecureRandomNumber { public static void main( String[] args ) throws NoSuchAlgorithmException { //Do the expensive one time setup of the // random number generator instance SecureRandom prng = SecureRandom.getInstance("SHA1PRNG"); //Get the next random number String randomNum = new Integer( prng.nextInt() ).toString(); System.out.println("Random number: " + randomNum); }}
38Friday, January 15, 2010
Result
Random number: 1633471380
39Friday, January 15, 2010
Digests & HashesOne way functions
40Friday, January 15, 2010
What is a Digest?
! Small set of bytes representing a large message
! Small change in message = large change in digest
! Integrity check for large data
! Password storage mechanism
OWASP says passwords should never be stored in plaintexthttp://www.owasp.org/index.php/Hashing_Java
41Friday, January 15, 2010
MessageDigest
! java.security.MessageDigest
! Multiple algorithms available! MD5 (128 bit)! SHA-1 (160 bit)
42Friday, January 15, 2010
MessageDigest
!MD5! U. S. Department of Homeland
Security said MD5"considered cryptographically broken and unsuitable for further use"
http://en.wikipedia.org/wiki/MD543Friday, January 15, 2010
http://xkcd.com/538/
$5 wrench XKCD: http://xkcd.com/538/Missy Elliott XKCD: http://xkcd.com/153/
44Friday, January 15, 2010
import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;
/** * Digest a string message via SHA1. * * Demonstrate that very similar messages * have radically different hashes. */public class MessageDigestSHA { public static void main( String[] args ) throws NoSuchAlgorithmException { //Set up the message to be encoded String message1 = "Four score and seven years ago"; String message2 = "Four score and seven tears ago"; System.out.println("Message1 SHA1 digest: " + shaAndBase64Encode(message1)); System.out.println("Message2 SHA1 digest: " + shaAndBase64Encode(message2)); } /** * Helper function to both SHA-1 hash and * base64 encode the resulting bytes to a String */ public static String shaAndBase64Encode(String message) throws NoSuchAlgorithmException { MessageDigest sha = MessageDigest.getInstance("SHA-1"); //Salt could be applied here //Integer salt = <some random number generator> //sha.update(salt.getBytes()); byte[] digest = sha.digest(message.getBytes()); return new sun.misc.BASE64Encoder().encode(digest); }}
45Friday, January 15, 2010
import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;
/** * Digest a string message via SHA1. * * Demonstrate that very similar messages * have radically different hashes. */public class MessageDigestSHA { public static void main( String[] args ) throws NoSuchAlgorithmException { //Set up the message to be encoded String message1 = "Four score and seven years ago"; String message2 = "Four score and seven tears ago"; System.out.println("Message1 SHA1 digest: " + shaAndBase64Encode(message1)); System.out.println("Message2 SHA1 digest: " + shaAndBase64Encode(message2)); } /** * Helper function to both SHA-1 hash and * base64 encode the resulting bytes to a String */ public static String shaAndBase64Encode(String message) throws NoSuchAlgorithmException { MessageDigest sha = MessageDigest.getInstance("SHA-1"); //Salt could be applied here //Integer salt = <some random number generator> //sha.update(salt.getBytes()); byte[] digest = sha.digest(message.getBytes()); return new sun.misc.BASE64Encoder().encode(digest); }}
46Friday, January 15, 2010
Input
Message1 SHA1 digest: DmCJIg4Bq/xpGIxVXxo3IB0vo38=Message2 SHA1 digest: oaLHt8tr31ttngCDjyYuWowF5Mc=
String message1 = "Four score and seven years ago";String message2 = "Four score and seven tears ago";
Result
47Friday, January 15, 2010
JDK KeytoolKey generation, storage & management
48Friday, January 15, 2010
Keytool
! Creates! Keystore! Truststore
! Functions! -genkey! -list! -import! -export! -certreq
49Friday, January 15, 2010
Creating a keystore
keytool -genkeypair -keyalg RSA -keysize 2048 -keystore myapp.keystore
Enter keystore password: ********Re-enter new password: ********
What is your first and last name? [Unknown]: Matthew McCulloughWhat is the name of your organizational unit? [Unknown]: Consulting What is the name of your organization? [Unknown]: Ambient Ideas, LLCWhat is the name of your City or Locality? [Unknown]: DenverWhat is the name of your State or Province? [Unknown]: ColoradoWhat is the two-letter country code for this unit? [Unknown]: US
Is CN=Matthew McCullough, OU=Consulting, O="Ambient Ideas, LLC", L=Denver, ST=Colorado, C=US correct? [no]: yes
Enter key password for <mykey>! (RETURN if same as keystore password):
50Friday, January 15, 2010
Creating a keystorekeytool -genkeypair -keyalg RSA -keysize 2048 -keystore myapp.keystore
Enter keystore password: ********Re-enter new password: ********
What is your first and last name? [Unknown]: Matthew McCulloughWhat is the name of your organizational unit? [Unknown]: Consulting What is the name of your organization? [Unknown]: Ambient Ideas, LLCWhat is the name of your City or Locality? [Unknown]: DenverWhat is the name of your State or Province? [Unknown]: ColoradoWhat is the two-letter country code for this unit? [Unknown]: US
Is CN=Matthew McCullough, OU=Consulting, O="Ambient Ideas, LLC", L=Denver, ST=Colorado, C=US correct? [no]: yes
Enter key password for <mykey>! (RETURN if same as keystore password):
51Friday, January 15, 2010
Using a keystore
java -Djavax.net.ssl.keyStore=keystore \ -Djavax.net.ssl.keyStorePassword=y3$1t1s \ ServerApp
Using a Truststore
java -Djavax.net.ssl.trustStore=truststore \ -Djavax.net.ssl.trustStorePassword=tru$tM3 \ ClientApp
52Friday, January 15, 2010
JSSENetwork communications security
53Friday, January 15, 2010
JSSE
! Java Secure Socket Extension
! Built on top of JCE
! Specific to networking
! Standard as of JRE 1.4
! Implementations of! Secure Sockets Layer (SSL) 2.0 and 3.0! Transport Layer Security (TLS) 1.0
http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.htmlPreviously an optional add on up through JRE 1.3
http://en.wikipedia.org/wiki/Transport_Layer_SecurityTLS 1.0 in 1999. Improvements to SSL 3.0 (1996)
54Friday, January 15, 2010
JAASAuthentication and Authorization
55Friday, January 15, 2010
JAAS
! Java Authentication and Authorization Service
! Single sign on helper
! Supports biometric, smartcard devices
! Adds “user” control(above code control)
56Friday, January 15, 2010
SYMMETRICMy key is your key
57Friday, January 15, 2010
Why Symmetric?
! Fast
! Bulk data
! Controlled environment
! Never decrypted at remote end
58Friday, January 15, 2010
Symmetric Problems
! Keys vulnerable to capture
! Eavesdropping on future communications after key compromise
! Key distribution challenges
! Triangular number key growth
How do you distribute keys?System-wide number of keys for N nodes to talk securely to any node is Tnhttp://mathworld.wolfram.com/TriangularNumber.html
59Friday, January 15, 2010
Symmetric Problems! Triangular number key growth
60Friday, January 15, 2010
DES & 3DES
! Block cipher
! DES is known to be broken
! 3DES and DESede
! basically three passes of DES
! Reasonably strong
61Friday, January 15, 2010
Blowfish
! Secure replacement for DES
! Faster than DES
! Block cipher
Sounds like a new flavor of Ben and Jerry’s ice cream62Friday, January 15, 2010
RC4
! Rivest’s code 4
! Stream cipher
63Friday, January 15, 2010
AES
! Advanced Encryption Standard
! Government standard! Rijndael algorithm
(Joan Daemen, Vincent Rijmen)! 4 years of evaluation! Final in December 2000
! Very Secure
! block cipher
64Friday, January 15, 2010
import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SymmetricEncrypt { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; //Build a new encryption key final KeyGenerator keyGen = KeyGenerator.getInstance("DESede"); keyGen.init(168); final SecretKey desKey = keyGen.generateKey(); //Set up the cipher final Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); ////////////////////////////////////// //Put the cipher in encryption mode desCipher.init(Cipher.ENCRYPT_MODE, desKey); //Encrypt and output the base64 data byte[] clearText = message1.getBytes(); byte[] encryptedBytes = desCipher.doFinal(clearText); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); ////////////////////////////////////// //Put the cipher in decryption mode desCipher.init(Cipher.DECRYPT_MODE, desKey); //Decrypt and output the original string byte[] decryptedBytes = desCipher.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
65Friday, January 15, 2010
import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SymmetricEncrypt { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; //Build a new encryption key final KeyGenerator keyGen = KeyGenerator.getInstance("DESede"); keyGen.init(168); final SecretKey desKey = keyGen.generateKey(); //Set up the cipher final Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); ////////////////////////////////////// //Put the cipher in encryption mode desCipher.init(Cipher.ENCRYPT_MODE, desKey); //Encrypt and output the base64 data byte[] clearText = message1.getBytes(); byte[] encryptedBytes = desCipher.doFinal(clearText); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); ////////////////////////////////////// //Put the cipher in decryption mode desCipher.init(Cipher.DECRYPT_MODE, desKey); //Decrypt and output the original string byte[] decryptedBytes = desCipher.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
66Friday, January 15, 2010
import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SymmetricEncrypt { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; //Build a new encryption key final KeyGenerator keyGen = KeyGenerator.getInstance("DESede"); keyGen.init(168); final SecretKey desKey = keyGen.generateKey(); //Set up the cipher final Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); ////////////////////////////////////// //Put the cipher in encryption mode desCipher.init(Cipher.ENCRYPT_MODE, desKey); //Encrypt and output the base64 data byte[] clearText = message1.getBytes(); byte[] encryptedBytes = desCipher.doFinal(clearText); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); ////////////////////////////////////// //Put the cipher in decryption mode desCipher.init(Cipher.DECRYPT_MODE, desKey); //Decrypt and output the original string byte[] decryptedBytes = desCipher.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
67Friday, January 15, 2010
import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class SymmetricEncrypt { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; //Build a new encryption key final KeyGenerator keyGen = KeyGenerator.getInstance("DESede"); keyGen.init(168); final SecretKey desKey = keyGen.generateKey(); //Set up the cipher final Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); ////////////////////////////////////// //Put the cipher in encryption mode desCipher.init(Cipher.ENCRYPT_MODE, desKey); //Encrypt and output the base64 data byte[] clearText = message1.getBytes(); byte[] encryptedBytes = desCipher.doFinal(clearText); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); ////////////////////////////////////// //Put the cipher in decryption mode desCipher.init(Cipher.DECRYPT_MODE, desKey); //Decrypt and output the original string byte[] decryptedBytes = desCipher.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
68Friday, January 15, 2010
Input
Encrypted text: P0FT6N3XXrohtsz7OLh3FGYY0wErkPIur1DP6Csbj4g=Decrypted text: Four score and seven years ago
String message1 = "Four score and seven years ago";
Result
69Friday, January 15, 2010
Encrypted isn’t enough?
http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation70Friday, January 15, 2010
ASYMMETRICThrowing away keys
faster than an intern locksmith
71Friday, January 15, 2010
http://www.isg.rhul.ac.uk/node/329http://www.isg.rhul.ac.uk/files/IMG_9819.JPGhttp://en.wikipedia.org/wiki/Diffie
72Friday, January 15, 2010
Diffie-Hellman
! Key Agreement Protocol
! Alice & Bob independently generate the shared (session) key
! asymmetric Key handshake
! 1970s
! Vulnerable to MITM attack! Fixed by
! PKI! signing the agreed key
http://en.wikipedia.org/wiki/Diffie–Hellman_key_exchange73Friday, January 15, 2010
DH Diagrammed
http://matdonline.free.fr/RSA-Diffie-Hellman-explained-in-5-minutes.htm
74Friday, January 15, 2010
RSAhttp://www.usc.edu/dept/molecular-science/pictures/RSA-2003.jpg
75Friday, January 15, 2010
RSA
! Ron Rivest, Adi Shamir, Leonard Adleman
! Published in 1978
! M.I.T. Patented in 1983
! Patent Expired in 2000
Not patented in many other countries due to paper published before patent.There was later found to be prior art might not have allowed this to get patented at all.
76Friday, January 15, 2010
import java.io.IOException;import java.security.InvalidKeyException;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class EncryptRSA { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; // Generate the Key Pair final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); final SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); keyGen.initialize(1024, random); KeyPair pair = keyGen.generateKeyPair(); final PrivateKey privKey = pair.getPrivate(); final PublicKey pubKey = pair.getPublic(); //Encrypt using the private key Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsa.init(Cipher.ENCRYPT_MODE, privKey); byte[] encryptedBytes = rsa.doFinal(message1.getBytes()); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); //Decrypt using the private key rsa.init(Cipher.DECRYPT_MODE, pubKey); byte[] decryptedBytes = rsa.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
77Friday, January 15, 2010
import java.io.IOException;import java.security.InvalidKeyException;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class EncryptRSA { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; // Generate the Key Pair final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); final SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); keyGen.initialize(1024, random); KeyPair pair = keyGen.generateKeyPair(); final PrivateKey privKey = pair.getPrivate(); final PublicKey pubKey = pair.getPublic(); //Encrypt using the private key Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsa.init(Cipher.ENCRYPT_MODE, privKey); byte[] encryptedBytes = rsa.doFinal(message1.getBytes()); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); //Decrypt using the private key rsa.init(Cipher.DECRYPT_MODE, pubKey); byte[] decryptedBytes = rsa.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
78Friday, January 15, 2010
import java.io.IOException;import java.security.InvalidKeyException;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class EncryptRSA { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; // Generate the Key Pair final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); final SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); keyGen.initialize(1024, random); KeyPair pair = keyGen.generateKeyPair(); final PrivateKey privKey = pair.getPrivate(); final PublicKey pubKey = pair.getPublic(); //Encrypt using the private key Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsa.init(Cipher.ENCRYPT_MODE, privKey); byte[] encryptedBytes = rsa.doFinal(message1.getBytes()); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); //Decrypt using the private key rsa.init(Cipher.DECRYPT_MODE, pubKey); byte[] decryptedBytes = rsa.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
79Friday, January 15, 2010
import java.io.IOException;import java.security.InvalidKeyException;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;
import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;
import sun.misc.BASE64Encoder;
/** * Use the SecureRandom java security class to generate * a more expensive, but cryptographically secure random number. */public class EncryptRSA { public static void main( String[] args ) throws NoSuchAlgorithmException, NoSuchProviderException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { final String message1 = "Four score and seven years ago"; // Generate the Key Pair final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); final SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); keyGen.initialize(1024, random); KeyPair pair = keyGen.generateKeyPair(); final PrivateKey privKey = pair.getPrivate(); final PublicKey pubKey = pair.getPublic(); //Encrypt using the private key Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsa.init(Cipher.ENCRYPT_MODE, privKey); byte[] encryptedBytes = rsa.doFinal(message1.getBytes()); BASE64Encoder b64e = new sun.misc.BASE64Encoder(); String base64Encrypted = b64e.encode(encryptedBytes); System.out.println("Encrypted text: " + base64Encrypted); //Decrypt using the private key rsa.init(Cipher.DECRYPT_MODE, pubKey); byte[] decryptedBytes = rsa.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted text: " + decryptedText); }}
80Friday, January 15, 2010
Input
Encrypted text: A8Is+4r7sDn28fD6IQvZiR5JxPs/vh7UnXrF38acJt6R/ARisj/zLtC7Xn6iJgNQPhc16wkVZhCFem7oNoim+ooTUDDZQ+E3qP6y/DZJGkLBoZuZVLeLAW1LUtHSzduRUOg1uMynJz14wxzwfV8wfRwfatpySkOhGqWS63bPNRs=Decrypted text: Four score and seven years ago
String message1 = "Four score and seven years ago";
Result
81Friday, January 15, 2010
OTHER FRAMEWORKSand alternative JCE providers
82Friday, January 15, 2010
Bouncy Castle
! JCE Provider
! Many more encryption and digest algorithms than the Sun provider (AES)
http://www.mobilefish.com/developer/bouncycastle/bouncycastle_quickguide_install.html
83Friday, January 15, 2010
JasyptFrictionless Java encryption
Works beautifully with Hibernate and The Spring Framework84Friday, January 15, 2010
GnuOpen source library
Hundreds of algorithms implementedhttp://www.gnu.org/software/gnu-crypto/
85Friday, January 15, 2010
WIFIYou are the weakest link
86Friday, January 15, 2010
WIFI Algorithms
TKIP
!WEP
!WPA
!WPA2AES
WEP can be sniffed for keysWPA2 implements the mandatory elements of 802.11i
87Friday, January 15, 2010
TJ Maxx
88Friday, January 15, 2010
TJ Maxx
! $1 billon USD final cost
! 45 million credit card numbers stolen
89Friday, January 15, 2010
“
”
Many security experts have criticized the
strength of WEP encryption. WEP was initially
cracked in 2001, and most recently broken by
German researchers last month
using an ordinary
laptop in under three
seconds— Tom Espiner, ZDNet UK
http://www.zdnetasia.com/news/security/0,39044215,62011583,00.htm
90Friday, January 15, 2010
WIFI Interception
! Hey Look! A MyFreeWIFI SSID...
! Tempting
! Ridiculously unsafe
91Friday, January 15, 2010
Tools of the Trade
!AirCrack!AirSnort!WireShark!Silent Proxies
92Friday, January 15, 2010
WEP Cracking
! Listen for packets! Slow! Untraceable
! Inject bad packets! Listen for reply! Faster
! leaves a footprint
93Friday, January 15, 2010
WireShark Demo
http://www.wireshark.org/94Friday, January 15, 2010
Upside-Down-TernetDemo
http://www.ex-parrot.com/pete/upside-down-ternet.html95Friday, January 15, 2010
96Friday, January 15, 2010
PRINTED MATERIALSDead tree propagation of security
97Friday, January 15, 2010
1997
98Friday, January 15, 2010
1998 Java 1.1 & 1.2
99Friday, January 15, 2010
2004 Java 1.4
100Friday, January 15, 2010
2005 Java 5
101Friday, January 15, 2010
2008
102Friday, January 15, 2010
ENCRYPTION BOOT CAMPsecurity mission completed
103Friday, January 15, 2010
ENCRYPTION BOOT CAMPsecurity mission completed
@matthewmccull
#EncryptBC
http://ambientideas.com/blog
http://speakerrate.com/matthew.mccullough
104Friday, January 15, 2010
REFERENCES
105Friday, January 15, 2010
! Sun docs! http://java.sun.com/javase/6/docs/technotes/
guides/security/crypto/CryptoSpec.html! http://java.sun.com/javase/technologies/security/! http://java.sun.com/javase/6/docs/technotes/
guides/security/jsse/JSSERefGuide.html! http://java.sun.com/javase/6/docs/api/java/
security/Security.html
! BouncyCastle JCE Provider! http://www.bouncycastle.org/documentation.html
References
106Friday, January 15, 2010
! Sample Code! http://github.com/matthewmccullough/
encryption-jvm-bootcamp
! Miscellaneous! http://www.ietf.org/rfc/rfc3852.txt! http://en.wikipedia.org/wiki/
Abstract_Syntax_Notation_One
References
107Friday, January 15, 2010
! CMS! Cryptographic Message Syntax (CMS)
objects! RFC 3852! PKCS#7 (formerly RFC 2630, 3369)! http://www.ietf.org/rfc/rfc3852.txt
! ASN.1! Abstract Syntax Notation One! 1984 X.409, 1988 X.208, 1995 X.680,
2002! http://www.asn1.org/
Acronyms
108Friday, January 15, 2010
CREDITS
109Friday, January 15, 2010
! http://www.ambientideasphotography.com! http://stockfootageforfree.com/! http://xkcd.com/538/! http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation! http://matdonline.free.fr/RSA-Diffie-Hellman-explained-in-5-
minutes.htm! http://www.isg.rhul.ac.uk/node/329! http://www.isg.rhul.ac.uk/files/IMG_9819.JPG! http://www.usc.edu/dept/molecular-science/pictures/RSA-2003.jpg! All others, iStockPhoto.com
110Friday, January 15, 2010
Outtakes
111Friday, January 15, 2010
Steganography
! Data in pictures! Not necessarily encrypted! Merely hidden in pedestrian files
112Friday, January 15, 2010
Steganography
! MP3! JPEG! DIVX! TCP Retry Packets! Email Headers
113Friday, January 15, 2010
Steganography
! High signal to noise ratio! Slow but
! Inconspicuous
114Friday, January 15, 2010
Cracks in the News
! Thomas Jefferson letter! London Tube Oyster cards! GSM! Iraq drone video feeds! Pacemakers! Zune! WPA! Blue-ray! DVD! Skype! Windows Vista BitLocker
Jefferson: All your liberty are belong to us!GSM: Yet another reason to switch away from AT&TZune: No one cared.
115Friday, January 15, 2010
Encryption & The Law
!Encryption considered a munition under international law
!1999 Relaxation of rules
116Friday, January 15, 2010
Digital Signatures
! Hash with Private Key
! Public Private Key Systems
! Public Key Infrastructure (PKI)
117Friday, January 15, 2010
Breakthroughs
! IBM! Statistics on encrypted data
! No compromise on security or anonymity
http://www.net-security.org/secworld.php?id=7690118Friday, January 15, 2010
Keys
! Clickers/Tokens
! One Time Pads (paper)
119Friday, January 15, 2010
! Message Digests == Hash?! Certificates (x509 v3)! Digital signatures
! Just means hashing a message, then signing the hash with the private key
! Later verified by decrypting the hash with the public key, then re-running the hash and comparing the two hashes.
! Block vs Stream ciphers
Misc
120Friday, January 15, 2010
Sign / Digest / Auth / Encrypt
Cryptographic Message Syntax
121Friday, January 15, 2010
Session Keys
! symmetric key exchanged securely by a private/public key initial transaction
122Friday, January 15, 2010
Elliptic Curve
! Faster than standard public key encryption
! ECC
! Based on elliptic curve logarithm problem
123Friday, January 15, 2010