當顧客想從 Web 站點購買某個產品時,顧客和 Web 站點都要進行認證。顧客通常是以提供名字和密碼的方式來認證他自己。另一方面,Web 站點通過交換一塊簽名數據和一個有效的 X.509 證書(作為 SSL 握手的一部分)來認證它自己。顧客的瀏覽器驗證該證書并用所附的公用密鑰驗證簽名數據。一旦雙方都認證了,則交易就可以開始了。
對等機 A 發起這項事務,每臺對等機相互認證,兩臺對等機協商采用的密碼及其長度并建立一個安全通道。完成這些操作之后,每個對等機都知道它正在跟誰交談并且知道通道是安全的。
初始化 因為 JSSE 和 SSL 的介紹對初始化代碼有很大影響,所以讓我們來考察對等機 A 中負責初始化的代碼。
清單 1. 安全初始化代碼 // Each peer has an identity that must be locally (but not globally) // unique. This identity and its associated public and private keys // are stored in a keystore and protected by a passWord. Each // peer also has a name that must be globally unique. String stringIdentity = null; String stringPassword = null; String stringName = null;
// The code that prompts the user for his/her identity // and password goes here. the user´s name is // generated (if necessary) later.
// Create home Directory. This is a very portable way // to create a home directory, but it has its problems -- // the various flavors of Microsoft Windows put the directory // in widely different locations in the directory hierarchy. String stringHome = System.getProperty("user.home") + File.separator + "p2p"; File fileHome = new File(stringHome); if (fileHome.exists() == false) fileHome.mkdirs();
// Create keystore. We must run an external process to create the // keystore, because the security APIs don´t eXPose enough // functionality to do this inline. I haven´t tested this widely enough // to know how portable this code is, but it works on everything I // tried it on. String stringKeyStore = stringHome + File.separator + "keystore"; File fileKeyStore = new File(stringKeyStore); if (fileKeyStore.exists() == false) { System.out.println("Creating keystore..."); byte [] arb = new byte [16]; SecureRandom securerandom = SecureRandom.getInstance("SHA1PRNG"); securerandom.nextBytes(arb); stringName = new String(Base64.encode(arb)); String [] arstringCommand = new String [] { System.getProperty("java.home") + File.separator + "bin" + File.separator + "keytool", "-genkey", "-alias", stringIdentity, "-keyalg", "RSA", "-keysize", "1024", "-dname", "CN=" + stringName, "-keystore", stringHome + File.separator + "keystore", "-keypass", stringPassword, "-storetype", "JCEKS", "-storepass", stringPassword }; Process process = Runtime.getRuntime().exec(arstringCommand); process.waitFor(); InputStream inputstream2 = process.getInputStream(); IOUtils.copy(inputstream2, System.out); InputStream inputstream3 = process.getErrorStream(); IOUtils.copy(inputstream3, System.out); if (process.exitvalue() != 0) System.exit(-1); }
// Once the application has created/located the keystore, it // opens it and creates a KeyStore instance from the data // in it. char [] archPassword = stringPassword.toCharArray(); FileInputStream fileinputstream = new FileInputStream(stringHome + File.separator +