![]() |
Distributed Systems Lab 2003 |
||||||||||||||||||||||||||||||||
|
![]() |
Lab 3: Making searches secureGeneral ExplanationsOverviewAgain the reminder (which really should not apply to anyone now) that if you have not yet read the overview description , you'd better do it now! The third lab deals with security issues. Our goal is to make the exchange of search messages between ShareMe peers secure - we do not consider the multicast 'IAmAlive' messages from lab1 or other communication such as the communication with the DSG certification authority or the file downloads themselves. A short introduction to network security, digital signatures and certificates is given in the DSG certification authority section . In this overview, we want to emphasize that we do not use a full security infrastructure in the lab and even the certification authority only provides a trusted key exchange facility (otherwise the implementation effort would be too big!). Thus, the DSG certification authority can be seen as a trusted directory service where public keys are registered. Normally, certificates would guarantee that the registrated information is correct and valid - we assume this implicitly in the lab. What it boils down to is that every peer has a private and a public key. The private key is kept secret and the public key is registered with the certification authority. In the first task of this lab you create a cryptography helper class which encapsulates all cryptographic functionality, i.e., the generation and management of (public and private) keys and the creation/verification of digital signatures. This helper class is subsequently used by other classes in the ShareMe system. The second task deals with another helper class, the security helper. The security helper is based on the cryptography helper from the first task and adds the CORBA communication with the certification authority to register and retrieve public keys. The third and last task of this lab example integrates the two helper classes with the already existing ShareMe system. In the end, all search requests and responses will be digitally signed and the signatures will be verified by the receivers. Reading SuggestionsFirst, recall what you already know about Java object serialization. If you need to refresh your memory, here is the corresponding lesson in the Java Tutorial. In the lab we use the Java security classes to implement digital signatures. The section on creating and verifying digital signatures in the Java tutorial explains all the necessary background. Actually, the tutorial even covers encoded key specifications which we replace with Java object serialization in the lab (for simplicity reasons). CORBA is a platform-independent specification for distributed computing. An overview of how to use CORBA with Java is found in the Java IDL documentation . Especially the introductory-level 'Hello World' tutorial section is a nice overview and gives some information about the interface definition language (IDL). Since in the lab you only have to develop a CORBA client to use the DSG CA Corba server, you can concentrate on the client-related information in the documentation. As of JDK 1.4.x, Java supports the Corba 2.3 specification and provides several server-side models (POA, POA-Tie, ImplBase) to implement Corba servers. Though the corresponding sections are interesting to read, you do NOT have to know them to implement the lab or answer lab test questions. Hint: Note that the JDK 1.4.x supports an updated version of the CORBA specification. Thus if you read any material on using Java with Corba, make sure you do not use outdated material. Also the IDL sections of the Java Tutorial currently do NOT cover the new stuff! Deliverable (Submission)Execute the following command line (in a single line!) in the $HOME/src directory of your lab account. Recall that your submissions are only accepted if they are done from your lab account! tar cvfz - `find . -name "*.java"` | uuencode submission.tgz | mail -s 3 rnabgabe@dslab.tuwien.ac.at Task DescriptionsTask 3.1: The Cryptography HelperIn the first task of this lab, we create a cryptography helper class which is used to manage your private and public key and provides methods to sign objects and verify signatures. This helper class will then be used by various other classes of the ShareMe system. Use the ShareMeException defined for the methods of this class to report any errors or problems. First create the at.ac.tuwien.infosys.rnue.implementation.security.CryptographyImpl class which implements the ICryptography interface. The constructor gets no parameters. In the body of the constructor create a Signature object with the MD5withRSA algorithm (Note that the RSA algorithm is NOT the same as the MD5withRSA algorithm). Throw a ShareMeException if an error occurs in the constructor, e.g., the signature object cannot be created. The job of the initialize method is to initialize the cryptography helper for future use: this means that a key pair consisting of a private and a public key has either to be read from a file (if the key pair exists) or has to be newly created. Thus you have to check if the specified key file exists; if so, read a KeyPair object from the file using Java object serialization (i.e., using an ObjectInputStream ). If the keyfile does not exist, you have to create a new keypair and store it in the specified file. To create a key pair, instantiate a KeyPairGenerator with the RSA algorithm. Then initialize it with IConstants.KEY_LENGTH which specifies the length of the key to be generated and invoke the KeyPairGenerator.generateKeyPair() method. Hint: The generation of a new key pair can take a while (up to a minute or so depending on the workload of the machine you are working on). Be patient! When the key generation is finished, store the keypair in the key file specified as parameter using object serialization (i.e., an ObjectOutputStream ). The return value of this method depends on whether you created a new key pair or not. If a new key pair was created, the public key is returned; otherwise return null . It is important later on to distinguish whether the initialization of the cryptography helper resulted in a new key or not to decide whether the key has to be registered at the certification authority or not (see next task). Once we have a key pair, we can implement the sign() and verify() methods. The sign method takes a serializable object, signs it and returns the signature. To do so,
The ICryptography.convertSerializableToByteArray() method is intended to convert a serializable object into a byte array. This method must use a ByteArrayOutputStream and ObjectOutputStream to create a byte array from a serializable object. Now only the verify() method is missing. To verify a given signature for a serializable object,
Equipped with this helper class to handle cryptographic functions for us, we can return to the ShareMe system and complete the security infrastructure there. Task 3.2: The ShareMe security ClassThe ShareMe security class is the primary (and only) contact for security issues in the ShareMe system. Thus it deals with signing and verifying search requests and responses, contacts the certification authority (CA) using CORBA to register the public key, and retrieves the public keys of remote peers from the CA. Check the interface definition file for the ShareMe certification authority service (shown below and available in your resources directory) to learn about the methods available! module CorbaCAImpl { exception CorbaCAException { string msg; }; typedef sequence<octet> KeyType; typedef sequence<string> ListType; interface ICertificationAuthority { boolean registerKey(in string owner, in KeyType key, in string password) raises (CorbaCAException); boolean unregisterKey(in string owner, in string password) raises (CorbaCAException); KeyType getKey(in string owner) raises (CorbaCAException); ListType registeredKeys() raises (CorbaCAException); }; }; If you read the Java IDL documentation , you will find out that the IDL file is pre-compiled into a set of stub classes. In the lab, you only need to create the client-side stubs. Check the Jakarta-Ant build.xml file to see how this is done. You don't have to invoke the idlj compiler yourself, everything is already done for you in the build.xml build file (however, you must know how to use idlj - this might be important for the exam!). The client-side stubs are generated from the IDL definition and stored in the corresponding Java package. Create the at.ac.tuwien.infosys.rnue.implementation.security.SecurityHelperImpl class that implements the ISecurityHelper interface (you need to import the org.omg.CORBA , org.omg.CosNaming and org.omg.CosNaming.NamingContextPackage CORBA packages). This class also has to provide a constructor that takes a java.util.Properties object as argument and throws an ShareMeException exception in case of an error. In the constructor of this class, several things have to be done: first we have to initialize the ORB used to contact the certification authority. A template for this task is shown below: // create and init the ORB ORB orb = ORB.init(new String[] {"-ORBInitialHost", orbHost, "-ORBInitialPort", orbPort}, null); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); // lookup the ca instance in naming this.ica = ICertificationAuthorityHelper.narrow(ncRef.resolve_str(IConstants.DSG_CA_NAME)); System.out.println("Server object resolved."); At the beginning the ORB object is intialized with the host and port the ORB is running on. These values can be retrieved from the properties using the IConstants.ORB_HOST and IConstants.ORB_PORT keys. Next the root naming context is retrieved using the fixed name 'NameService' . The narrow() method implements the casting of the generic org.omg.CORBA.Object instance to the NamingContextExt class. Use this instance's resolve_str() method to resolve the DSG CA service name to an object - the CA's name is specified in IConstants.DSG_CA_NAME . Finally, the ICertificationAuthorityHelper object (this interface is generated from the CORBA IDL and is put in the at.ac.tuwien.infosys.rnue.security.CorbaCAImpl package) can be retrieved using the narrow() method. When you finished the CORBA initialization, you can now create a new cryptography helper object (which you implemented in task 3.1) and initialize it with the parameters stored in the properties using the keys IConstants.HUMAN_READABLE_NAME and IConstants.KEYFILE_NAME . If the initialize method returns a non-null public key, you have to register the key at the certification authority invoking the registerPublicKey() method you'll implement in the next step. If the method returns null , this means that the private/public keypair existed and is already registered with the certification authority. Implementing the registerPublicKey() method is straight-forward. Convert the public key to be registered to a byte array using the convertSerializableToByteArray() method of the cryptography helper from the previous task. Then call the certification authority's registerKey() method. You can specify an arbitrary password which is stored together with your key. This password allows you to unregister your key programmatically using the certification authority's unregisterKey() method. Retrieving a public key from the certification authority in the getPublicKeyFromCA() method is equally simple. Just call the CA's getKey() method and convert the received byte array to a public key object using object serialization again. A ByteArrayInputStream and ObjectInputStream will do the job. Hint: The unregisterKey() method in the CA interface is merely for testing purposes; thus if you register a key and then your ShareMe peer crashes, you can use a helper program and the unregisterKey() method to get rid of the registered public key. To simplify this task for you we provide a servlet that let you unregister your public key at the CA. The servlet can be found in the Lab Environment DS Lab Status section. Click on unregister and provide the password. You can also simply choose another owner name to register the key with. Finally, implement the verify() and sign() methods by simply delegating the request to the corresponding methods of the cryptography helper class. Task 3.3: Integrate the security infrastructure with the ShareMe implementationFirst of all, you have to extend the constructor of the ShareMeImpl class to create a new instance of your implementation of the ISecurityHelper interface. Next, the ShareMeImpl.search() method has to be updated to sign outgoing requests and verify incoming responses. To sign a request, simply sign the search string using the sign method of the security helper. From now on, all your requests have to be signed. The returned signature byte array can then be used in the constructor of the search request. To verify the signature of a search response, you have to retrieve the public key of the sender. Contact the certification authority using the human readable name of the sender as stored in the IHostInfoMessage . Then get the signature of the file list included in the response and verify it using the security helper object. Include only search results which can be successfully verified in the final result (i.e., all unsigned or wrongly signed responses are ignored!). In any case return a result object - even if no hits were found and it is empty. The other place where you have to integrate the security functionality is the server object implementing the remote ISearchEngine interface. The ISecurityHelper of the ShareMeImpl is now passed to the server object in the constructor. In the search() method the reverse process is executed: first the signature of the incoming request is verified (i.e., again the public key is retrieved from the CA, the signature extracted from the request and verified using the security helper class). If an incoming search request is not signed (e.g., because a student implementation does not yet support signatures), you should accept the request but also reply with an unsigned response (i.e., use null as signature). If the signature of an incoming request is invalid, throw a ShareMeException . In the next step, the search is executed and the resulting IFileList object is signed (or not if the request was unsigned!). The resulting signature (or null for unsigned requests) is used in the constructor of the ISearchResponse which is returned to the client at the end. Now you can again test your ShareMe implementation using the same command line as in lab 2; the first time you start your implementation, a new key pair is generated and stored in the file system. Subsequent test runs only read the keys from the file. Consequently, all requests should be signed and all responses verified. |
![]() |
||||||||||||||||||||||||||||||
![]() |
![]() |
||||||||||||||||||||||||||||||||
Powered by MyXML |
Last update on:
2003-03-13
© 2001 Distributed Systems Group |