/** * Get the secret data that has been agreed on through Diffie-Hellman key agreement protocol. Note * that in the two party protocol, if the peer keys are already known, no other data needs to be * sent in order to agree on a secret. That is, a secured message may be sent without any * mandatory round-trip overheads. * * <p>It is illegal to call this member function if the private key has not been set (or * generated). * * @param peerPublicKey the peer's public key. * @returns the secret, which is an unsigned big-endian integer the same size as the * Diffie-Hellman modulus. */ SecretKey getAgreedSecret(BigInteger peerPublicValue) { try { KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman"); DHPublicKeySpec spec = new DHPublicKeySpec(peerPublicValue, modulus, base); PublicKey publicKey = kf.generatePublic(spec); KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman"); ka.init(privateKey); ka.doPhase(publicKey, true); return ka.generateSecret("TlsPremasterSecret"); } catch (GeneralSecurityException e) { throw new RuntimeException("Could not generate secret", e); } }
static DHPublicKeySpec getDHPublicKeySpec(PublicKey key) { if (key instanceof DHPublicKey) { DHPublicKey dhKey = (DHPublicKey) key; DHParameterSpec params = dhKey.getParams(); return new DHPublicKeySpec(dhKey.getY(), params.getP(), params.getG()); } try { KeyFactory factory = JsseJce.getKeyFactory("DH"); return (DHPublicKeySpec) factory.getKeySpec(key, DHPublicKeySpec.class); } catch (Exception e) { throw new RuntimeException(e); } }