/** * Certificate_Verify(証明書)を受け取ったときの動作をします。 * * @param line クライアントから受信した文字列 * @return クライアントの証明書の真偽 * @author kinbara */ private boolean recieveCertificateVerify(String line) { boolean cert_verify = false; // サーバー側のダイジェストのハッシュ値 ListIterator listIte = netDigest.listIterator(); String digest = ""; while (listIte.hasNext()) { digest += listIte.next().toString(); } digest = digest.substring(0, digest.indexOf("Certificate_Verify")); BigInteger digest1 = new BigInteger(this.getHash(digest), 16); // クライアントの公開鍵で復号 BigInteger digest2 = new BigInteger(line.substring(line.indexOf(":") + 1), 16); try { X509 x509 = new X509("src/sglserver/conf/key/ca", "CAKeyStore", this.storePasswd); // TODO:(注意)ユーザーの公開鍵をpeerNameでCAKeyStoreに登録している場合のみ有効 RSAPublicKey pk = x509.getRSAPublicKey(peerName); digest2 = digest2.modPow(pk.getPublicExponent(), pk.getModulus()); // 復号 // b = a.modPow(s, n); → a mod n のs乗がbに代入される // pk.getPublicExponent()→公開指数 // pk.getModulus()→pkのmod値 } catch (Exception e) { e.printStackTrace(); } if (digest1.compareTo(digest2) == 0) { System.out.println(socket.getRemoteSocketAddress() + "は、信頼できます。"); cert_verify = true; } else { System.out.println(socket.getRemoteSocketAddress() + "は、危険です。"); } return (cert_verify); }
/** * Client_Key_Exchangeを受け取ったときの動作をします。 * * @param line クライアントから受信した文字列 * @throws CertificateException * @throws IOException * @throws KeyStoreException * @throws NoSuchAlgorithmException * @throws UnrecoverableKeyException * @author kinbara */ private void recieveClientKeyExchange(String line) throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { X509 x509 = new X509("src/sglserver/conf/key/ca", "CAKeyStore", this.storePasswd); RSAPrivateKey sk = x509.getRSAPrivateKey("server", this.keyPasswd); // 暗号化されたプリマスターシークレットの抽出 line = line.substring(line.indexOf(":") + 1); BigInteger preCipher = new BigInteger(line, 16); // プリマスターシークレットを復号 preMastarSecret = preCipher.modPow(sk.getPrivateExponent(), sk.getModulus()); // (事前共有鍵)=(秘密鍵). modPow((s乗:すなわちaのs乗),(元:すなわちg)) // b = a.modPow(s, n); a mod n のs乗がbに代入される }
/** * Server_Certificateメッセージを作成します。 * * @return Server_Certificateメッセージの文字列 * @author kinbara */ private String setServerCertificate() { String ans = "Server_Certificate"; ans += ":"; // 証明書の送信 // サーバーが自分の証明書に署名 try { X509 x509 = new X509("src/sglserver/conf/key/ca", "CAKeyStore", this.storePasswd); byte[] sign = x509.sign("server", this.keyPasswd); // 署名 for (int i = 0; i < sign.length; i++) { int val = sign[i] & 0xFF; if (val < 16) { ans += "0"; } ans += Integer.toHexString(val); } } catch (Exception e) { e.printStackTrace(); } // ダイジェストに追加 netDigest.add(ans); return (ans); }