580 likes | 735 Views
MT311 (Oct 2004) Java Application Development. Java Security, Cryptography, Authentication, PKI, Digital Signature & SSL. Tutorial 4. Tutor Information. Edmund Chiu (Group 4) Email: gianted@netvigator.com OR t439934@ouhk.edu.hk Please begin your email subject with [MT311]
E N D
MT311 (Oct 2004)Java Application Development Java Security, Cryptography, Authentication, PKI, Digital Signature & SSL Tutorial 4
Tutor Information • Edmund Chiu (Group 4) • Email: gianted@netvigator.com ORt439934@ouhk.edu.hk • Please begin your email subject with [MT311] • Webpage: http://learn.ouhk.edu.hk/~t439934
Security Issues in Java • When a computer is connected to a network, it is not enough to have physical security alone. • Communication security is a concern when computers communicate across a network • In Java applications, there are two main areas of security issues: • System security – safety and stability of the computing environment against malicious applications (e.g. virus) • Information security – the secrecy and integrity of data
Sandbox Model • In early days, Java use a basic security model called the sandbox model • Local applications are considered as trustable and are granted full access to the system • Download applets are not trusted and could not use any local resources • It is a quick solution related to downloaded applications at that time, but • has lots of shortcomings because you can either trust or not trust the entire application/applet • Cannot prevent a local application downloaded from the Internet from accessing a sensitive file • Even printing from an applet is impossible
Security Policy Model • In a security policy model, resource can be granted or denied different access independently • For example, if the resource is a file, you can grant a “read”, “write”, “execute” and “delete” permission • We can grant different types of permission to the following different resources also • Audio, AWT, Network, Property, Runtime and etc • Details are given in the Java Documentation on Security • To provide an even more flexible implementation, Java allows different policies to apply to different application, or even to different invocations of the same application.
Applet Security • Consider an Applet writing a file to your PC • Click Here to view the Applet source code (AppletSecurityTest.java on course homepage) • By default, Sandbox Model is used • Access denied. A security exception is shown in the applet
Applying Security Policy in Applet • You local PC needs to release the restriction by specifying a different policy grant { permission java.io.FilePermission "AppletSecurityTest.txt", "write";}; • Save the above text as a policy file named “policy.AllowWrite” in you current directory • View your applet using applet viewer applying the policy appletviewer -J-Djava.security.policy=policy.AllowWrite AppletSecurity.html
Security Policy • As in the previous example, you can see a policy is identified in the following format: permission <permission> <target> <action>; • Permission type (java.io.FilePermission) • The target source (AppletSecurityTest.java) • The action (write) • You can also specifying the permission for applets loaded from a URL specified by the code base grant codeBase http://java.sun.com/- { permission java.io.FilePermission “<<ALL FILES>>”, “write”; }; grant codeBase http://www.microsoft.com/- { permission java.io.FilePermission “<<ALL FILES>>”, “read”; };
Using the Policy Tool • To save the time and avoid from making mistakes that will lead to security vulnerabilities, Java provides a GUI tool policytool to manage the policies
Code Signing • We can grant a permission to applets from a particular URL to access our computer • URL can be hijacked or forged, how can we really know the applet file is from the exact party • Java provides another layer of security called code signing • To apply code signing, you need: • Create a JAR file (Java Archive, which is Java’s mechanism for bundling multiple files) using jar tool (Details) • Sign it using a Java tool jarsigner. You need a key pair generated by Java keytool to sign the JAR file (Details) jarsigner <jar_file> <key_file>
Code Signing II • The HTML code to read a jarred applet <applet code = AppletClassName.class archive=“JarFileNaem.jar” width=XXX height=YYY> • When the runtime loads a JAR file, it verifies if the JAR file has been signed and determine if it can be trusted • A signed JAR file authenticates the file owner and integrity of the signed files in the JAR archive • Web browser can apply a standard policy to trust an applet if the applet is signed by a trusted authority
Java Archive (JAR) • What is in a JAR file? • Create by: jar cf <jar_file> <all_files> • Execute by: java –jar myJAR.jar • Can also be viewed, extracted or even executed (Main-Class header is required in the Manifest file) • After code signing, the JAR files includes the class files, a fingerprint of the jarred files, code signer’s credentials, expiry date, the manifest and other related information • Fingerprint is an unique authentication token generated using a one-way hash algorithm – any alteration in code will generate a totally different fingerprint • Manifest is the directory of the archive – listing the files, the signatures, and other information (like Main-Class)
Cryptography • The main objectives of cryptography are: • Confidentiality – the information cannot be understood by others whom were not intended • Integrity – the information cannot be altered in the transition between sender and intended receiver without being detected • Non-repudiation – sender cannot deny his/her intention of sending/creating a message • Authentication – the sender and receiver can confirm other’s identity and the origin/destination of the information
Secure Communication • The simplest form of secure communication • Sender and recipient agree on a shared key • Communication is encrypted using the shared key • Only the objective of confidentiality is achieved
Sending a Message Securely • Steps of sending messages achieving all four cryptography objectives • Encrypt the original message with sender’s secret key • Confidentiality and authentication – encryption done using sender’s secret key • Create a message digest of the message • Integrity – digest is unique to the message • Encrypt the encrypted message and the message digest using the sender’s secret key • Non-repudiation – digest and message were encrypted together • Encrypt the encrypted message, message digest and the sender’s signature with the recipient's secret key • Authentication and confidentiality – only recipient can decrypt the message
Receiving a Message Securely • Steps of receiving messages in a secured way • Decrypt the package with the recipient’s key • Decrypt the pieces with the sender’s key • Compute the message digest to verify the integrity of the message • Decrypt the encrypted message using the sender’s key
Problem in a Secret-Key Algorithm • We require a number of secret keys, one for each step • The sender and recipient need to agree on the secret keys used in steps 1 and 2. • The sender and recipient need to give their secret keys to each other • If sender uses the same key for all recipients, the key in not secret then. • If sender uses different keys for each recipient, key management is complex • Key distribution is difficult, especially when the two parties are previously unknown
Public-Key Algorithm • Each party has a pair of keys • public key –made public to all parties you want to communicate with • private key –kept confidential • The key pair is generated using mathematical properties of prime number. • Each key pair is unique • It is difficult to compute the private key from the public key • The key pair has an interesting property • Decrypt (Encrypt(message, privateKey), publicKey) = message • Decrypt (Encrypt(message, publicKey), privateKey) = message
Public-Key Algorithm (cont’d) • How public-key algorithm achieve the objectives • Confidentiality and integrity can be achieved when used with signatures • Non-refutable – the private key is secret and there is only one right combination of public/private keys • Authentication – a message that A can read will be encrypted using A’s public key, only A, who have the respective private key can read the message • Messages in public-key algorithm • Sender: Encrypt( Encrypt(msg, SendPrivKey), RecPubKey) • Recipient: Decrypt( Decrypt(msg, RecPriKey), SendPubKey) • Key distribution problem is solved because public key can be made available publicly.
Symmetric Algorithm (Shared Key) • Public key algorithm uses two different keys for encryption and decryption – we call it an asymmetric algorithm • Public key algorithm requires a lot of computations • In practical, public key algorithm is used to establish the identities of the two parties and exchange a session key • Symmetric algorithm (shared key algorithm) use the same key for encryption and decryption • Decrypt (Encrypt (message,key), key) = message • The session key agreed in the above step is used to encrypt and decrypt the communication after the initial handshake
Java Cryptography Extension (JCE) • JCE provides cryptographic functions, include • Key generation • Encryption/decryption • Message digest • Certificates and more… • The standard APIs are defined, but the implementation can be substituted • JDK 1.4.2 includes some service implementation provided by Suns • You can still easily install other cryptography providers implementation (like IBM’s) to the Java Security API and the implementation should still work • Advantages: Different algorithm can be used – some may only trust certain cryptographic implementation
Some commonly used Cryptographic Services • SecureRandom – SHA1PRNG • KeyGenerator – DES, TripleDES, Blowfish • KeyPairGenerator – DSA, RSA, DH • MessageDigest – SHA1, MD5 • MAC – HmacMD5, HmacSHA1 • Signature – SHA1withDSA, SHA1WithRSA • CertificateFactory – X509 • Cipher – DES, TripleDES, Blowfish • KeyAgreement – DH • List can be retrieved through Provider class in java.security package (see ListCSPs.java for details)
Encryption and Decryption Plain text Cipher text Encrypt Decrypt
Encryption Strength • Encryption algorithms are measured by their strength • Example: 64-bit SSL and 128 bit-SSL • Key lengths provide a basic measure of strength when the same protocol is used • 128-bit SSL is 264 stronger than 64-bit SSL • Actually, the strength also depends on other factor, e.g., randomness of keys • Key lengths are not comparable when different algorithm is used • In RSA, when not all possible keys are valid, typical RSA keys are 1024-bit or even 2048-bit.
Secret-Key Encryption and Decryption • Most encryption and encryption are based on secret key algorithm • DES (Data Encryption Standard) was the de facto standard until recently • 56-bit key length • Possible to break a DES encryption by searching all possible keys – in less than 23 hours using 100,000 computers in 1999 • Now, Triple-DES is used by running DES three times using three different key • Newer standard used in US government is AES (Advanced Encryption Standard) • More extensible algorithm whose strength can be extended by using different key lengths
Using JCE to Encrypt/Decrypt a Message • Java cryptographic APIs are defined in java.security and javax.crypto pacakges • For a basic encryption, we need a secret key and a cryptographic algorithm • javax.crypto.SecretKey • javax.crypto.Cipher • To create a SecretKey, • we first need a KeySpec (e.g, javax.crypto.spec.DESKeySpec), which defines the attributes of the cryptographic key • KeySpec is then passed to a SecretKeyFactory in which the actual SecretKey object is created
Creating a Secret Key (DES Key) // the key itself as a byte array byte[] key = {'a','b','c','d','e','f','g','h'}; // create a DESKeySpec for out key DESKeySpec spec = new DESKeySpec(key); // retrieve a DES SecretKeyFactory SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); // generate the actual SecretKey object SecretKey secret = factory.generateSecret(spec); • DES key = 56-bit 7 bytesHowever, it is customary to initialize a 8-byte array and use the lower 7 bytes only (InvalidKeyException if only 7 bytes are input) • The secret key can be printed out by using secret.getEncoded().bytesToHexString()
Creating a Cipher • To create a cipher, you need to specify a right provider and call the getInstance static method from the Cipher class • Cipher c = Cipher.getInstance("DES"); • Then, you can initialize the Cipher object to either encrypt or decrypt a message (reinitialize will clear all previous data) • c.init(Cipher.ENCRYPT_MODE, secret); • secret refers to the key you obtained in the secret key factory • Now, you can call the update method to encrypt/decrypt the message (repeatedly call to process multi-parts) • c.update(buffer); // buffer is a byte array • To retrieve the encrypted/decrypted result, you invoke the doFinal method • Byte[] isEncrypted = c.doFinal(); • Please refer to API specification for other forms of update/doFinal
Encryption and Decryption Example DESEncrypt.java • Main method • Open a file, encrypt the contents and write the encrypted data in another file • encrypt method • Create a cipher and initialize it using the secret key in the input parameter • Encrypt the input byte array and return the encrypted result • makeDESKey method • Create and return a DES cryptographic key according to the given byte array DESDecrypt.java • Exactly the same as DESEncrypt.java except the Cipher is initialized to decrypt instead of encrypt
Encrypted Echo Server/Client • The Echo server/client can have a more secured communication by adding DES encryption/decryption • Messages cannot be processed if the key was wrongly typed • See: • DESEchoServer.java • DESEchoClient.java
AES Encryption and Decryption • In AES, apart from creating the KeySpec, we need to also create a IvParameterSpec for the initialization vector • Example: IvParameterSpec params = new IvParameterSpec(iVBytes); • We call Cipher's init method with the mode (encrypt/decrypt), keySpec and the parameterSpec: • Example:cipher.init(Cipher.ENCRYPT_MODE, key, params);
Message Digest • Message digests is used to guarantee the integrity of a message, is also known as a fingerprint or a hash. • A message digest is generated using a mathematical transformation called a hash function • The resultant message digest is typically fixed length • The hash function used to produce message digest should have the following properties: • Extremely difficult to produce a same message digest from two different messages – the hash must be one-to-one • Extremely difficult to produce the original message from a given message digest – the hash must be irreversible • The most popular algorithms are SHA1 and MD5.
MD5 Algorithm • MD5 algorithm takes in a message of arbitrary length and produces a 128-bit or 16-byte message digest • MD5 is popular because it is one of the faster message digest algorithm • MD5 ensure a download file has not tampered by providing a MD5 checksum • After the file is downloaded, MD5 checksum is generated and checked against the original one • In this way, two parties can know the secret without transferring the secret itself • Example: a password's hash is transferred to a homepage and the hash is checked with the hash stored in the web server
Message Digest in Java • Message digests are encapsulated in the class java.security.MessageDigest • Like Cipher, we create a MessageDigest using getInstance method MessageDigest md = MessageDigest.getInstance("MD5"); • Data can then feed in to the MessageDigest object using the update method md.update(buffer); // buffer is a byte array • The hash is retrieved using the digest method md.digest(); • See the sample code in MD5.java
SHA1 and Keyed MD5 • SHA1 is similar to MD5 but it produces a 160-bit message digest. • Going back to the previous password handling technique • Man-in-the-middle can still impersonate the user without knowing the actual password • To prevent the man-in-the-middle attack, we modify the protocol to a challenge-and-response authentication • Server sends the client a random string • The client computes the MD5 hash of the random string using the password as a secret key • Previously computed hash cannot be reused because the string is randomly generated each time
Message Authentication Code (MAC) • MAC (message authentication code) is similar to a message digest, but with the addition of a secret key. • In addition to integrity, MAC also ensures the authenticity of the message digest • MAC still has the same key distribution problem • To generate a MD5 MAC, we first create the necessary key from javax.crypto.KeyGenerator KeyGenerator kg = KeyGenerator.getInstance("HmacMD5"); SecretKey sk = kg.generateKey(); • MAC object is then created and initialized using the key Mac mac = Mac.getInstance("HmacMD5"); mac.init(sk); • Data is then feed into the MAC object and the resultant code can be retrieved using doFinal mac.update(buffer); // buffer is a byte array byte[] result = mac.doFinal();
Public-Key Infrastructure (PKI) • Public-key algorithm solve the key distribution issue • Public key is distributed widely • Anyone can send you a message that only you can read • If message was also encrypted with the sender's private key, you can also verify the identity of the sender • But, how do we know a particular public key really belongs to a particular person? • Instead of distributing the public keys in PKI, the public keys are distributed as certificates • Certificates should contain enough info to authenticate the owner and associate the owner of a particular public key • Most popular standards for certificates include X.509 and PGP
Certificate Authorities • How do you know the certificate is authentic • It needs to be signed by a trusted party called the Certificate Authority (CA) using CA's private key – it validate the integrity and authenticity of the cert. • To verify a certificate, we check the signature using CA's public key, obtainable from CA's root certificate (self-signed) • CA must guarantee its own private key has not been compromised • All certificate related classes in Java are in java.security.cert package • java.security.cert.Certificate • java.security.cert.X509Certificate
Keys Management • Keys and certificates can be stored in binary or text files, and in Java, a special format called key store. • To create a key store and generate a certificate, you can invoke keytool as: keytool –keystore myKeyStore –genKey –alias myKey • Password is required for the key store • You will also be prompted for the information necessary for the X.509 certificate
Certificates Management • The certificate created by the recent step can be exported by calling: • For binary file export: keytool -keystore myKeyStore -storepass <passwd> -alias <myKey> -export –file <file> • For text format export: keytool -keystore myKeyStore -storepass <passwd> -alias <myKey> -export –rfc –file <file> • The certificates generated by keytool are self-signed
Using Certificate in Java • Import a certificate from a file FileInputStream is = new FileInputStream(file); CertificateFactory cf = CertificateFactory.getInstance("X.509"); Certificate cert = cf.generateCertificate(is);
Information within the Certificate • Information within a cert is abstracted as Principle • Subject is retrieved by: Principal p = cert.getSubjectDN(); // p.getName() will return the subject • Issuer is retrieved by:Principal p = cert.getIssuerDN();// p.getName() will return the issuer name • See ViewCert.java
Verifying the Certificate • To verify the certificate • Get the public key from the cert. (normally from CA's cert):PublicKey key = cert.getPublicKey(); • Verify the certificate using the public keycert.verify(key); // give out exceptions if verification fails • Possible exceptions in a certificate • NoSuchAlgorithmException • InvalidKeyException • NoSuchProviderException • SignatureException • CertificateException • See ViewCert2.java
Other Certificate Issues • Trust is transitive in most PKI • Certificate can be chained • Once you validate a certificate, you need to validate all intermediate certificates • Revocation • Certificates that are no longer valid is to be put in the certificate revocation lists
Comparing Secret-Key and Public-Key Algorithm • Secret-key are much faster than public-key • Public key requires certificate authorities as a trusted third party • Secret-key requires pre-agreement on keys and key distribution using public key is easier (using certificates)
Digital Signature • Secret-key MAC key distribution problem revisit • Can be solved by using private key to generate MAC and use public key to verify it – too slow • Hash the message and sign using our private key, the process is called digital signing • Digital signature verifies the identity and integrity of the message
Digital Signature in Java • In Java, java.security.Signature contains the function used in digital signing • The most popular algorithm used is Digital Signature Algorithm (DSA) • Key pair is first generated • KeyPairGenerator kpg = new KeyPairGenerator.getInstance("DSA"); • Then, initialize the key generator with the desired length • kpg.intialize(1024, new SecureRandom()); • The key pair can be generated according to followings • KeyPair keypair = kpg.generateKeyPair(); • DSAPublicKey public = (DSAPublicKey) keypair.getPublic()); • DSAPrivateKey private = (DSAPrivateKey) keypair.getPrivate());
Digital Signature in Java (cont'd) • The signing process Signature sign = Signature.getInstance("DSA"); sign.initSign(privateKey); sign.update(buffer); return sign.sign(); // signature is created • The verifying process Signature sign = Signature.getInstance("DSA"); sign.initVerify(privateKey); sign.update(buffer); return sign.verify();
Other Issues on Digital Signature • A DSA algorithm requires a key of at least 1024 bits and the resultant signature is 46-bytes long • Though we can create a DSA for the entire message, it works very slowly. • Thus, it is typical we create a hash for the message first, and use DSA to sign the hash only
Before Starting SSL • Special Notes: Please ignore the Installation Notes in your Course Materials if you use JDK1.4.x. It is for previous versions only.