下面列出了javax.crypto.KeyAgreement#doPhase ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static ECDHKeySet getSharedSecret (ECKey keyServer, ECKey keyClient) {
try {
ECPrivateKeySpec specPrivate = new ECPrivateKeySpec(keyServer.getPrivKey(), ecParameters);
ECPublicKeySpec specPublic = new ECPublicKeySpec(new ECPoint(keyClient.getPubKeyPoint().getXCoord().toBigInteger(), keyClient.getPubKeyPoint()
.getYCoord().toBigInteger()), ecParameters);
ECPrivateKey privateKey = (ECPrivateKey) kf.generatePrivate(specPrivate);
ECPublicKey publicKey = (ECPublicKey) kf.generatePublic(specPublic);
JCEECPrivateKey ecPrivKey = new JCEECPrivateKey(privateKey);
JCEECPublicKey ecPubKey = new JCEECPublicKey(publicKey);
KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDH");
aKeyAgree.init(ecPrivKey);
aKeyAgree.doPhase(ecPubKey, true);
return new ECDHKeySet(aKeyAgree.generateSecret(), keyServer.getPubKey(), keyClient.getPubKey());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void testAlgorithm(KeyAgreement ka1, KeyPair kp1,
KeyAgreement ka2, KeyPair kp2, String algorithm) throws Exception {
SecretKey key1;
ka1.init(kp1.getPrivate());
ka1.doPhase(kp2.getPublic(), true);
System.out.println("Derive " + algorithm + " using SunJCE...");
key1 = ka1.generateSecret(algorithm);
ka2.init(kp1.getPrivate());
ka2.doPhase(kp2.getPublic(), true);
System.out.println("Derive " + algorithm + " using PKCS#11...");
SecretKey key2 = ka2.generateSecret(algorithm);
byte[] b1 = key1.getEncoded();
byte[] b2 = key2.getEncoded();
if (Arrays.equals(b1, b2) == false) {
System.out.println(b1.length + " bytes: " + toString(b1));
System.out.println(b2.length + " bytes: " + toString(b2));
throw new Exception(algorithm + " secret mismatch");
}
}
private SecretKey t12DeriveKey(String algorithm,
AlgorithmParameterSpec params) throws IOException {
try {
KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
ka.init(localPrivateKey);
ka.doPhase(peerPublicKey, true);
SecretKey preMasterSecret =
ka.generateSecret("TlsPremasterSecret");
SSLMasterKeyDerivation mskd =
SSLMasterKeyDerivation.valueOf(
context.negotiatedProtocol);
if (mskd == null) {
// unlikely
throw new SSLHandshakeException(
"No expected master key derivation for protocol: " +
context.negotiatedProtocol.name);
}
SSLKeyDerivation kd = mskd.createKeyDerivation(
context, preMasterSecret);
return kd.deriveKey("MasterSecret", params);
} catch (GeneralSecurityException gse) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(gse);
}
}
/**
* Handle the TLSv1-1.2 objects, which don't use the HKDF algorithms.
*/
private SecretKey t12DeriveKey(String algorithm,
AlgorithmParameterSpec params) throws IOException {
try {
KeyAgreement ka = KeyAgreement.getInstance(algorithmName);
ka.init(localPrivateKey);
ka.doPhase(peerPublicKey, true);
SecretKey preMasterSecret
= ka.generateSecret("TlsPremasterSecret");
SSLMasterKeyDerivation mskd
= SSLMasterKeyDerivation.valueOf(
context.negotiatedProtocol);
if (mskd == null) {
// unlikely
throw new SSLHandshakeException(
"No expected master key derivation for protocol: "
+ context.negotiatedProtocol.name);
}
SSLKeyDerivation kd = mskd.createKeyDerivation(
context, preMasterSecret);
return kd.deriveKey("MasterSecret", params);
} catch (GeneralSecurityException gse) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(gse);
}
}
private static void testKeyAgreement(KeyPair kpA, KeyPair kpB, Provider p)
throws Exception {
KeyAgreement ka1 = KeyAgreement.getInstance("ECDH", p);
ka1.init(kpA.getPrivate());
ka1.doPhase(kpB.getPublic(), true);
byte[] s1 = ka1.generateSecret();
KeyAgreement ka2 = KeyAgreement.getInstance("ECDH", p);
ka2.init(kpB.getPrivate());
ka2.doPhase(kpA.getPublic(), true);
byte[] s2 = ka2.generateSecret();
if (Arrays.equals(s1, s2) == false) {
System.out.println("expected: " + toString(s1));
System.out.println("actual: " + toString(s2));
throw new Exception("Generated secrets do not match");
}
}
/** This test tries a key agreement with keys using distinct parameters. */
@SuppressWarnings("InsecureCryptoUsage")
@Test
public void testDHDistinctParameters() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");
keyGen.initialize(ike1536());
KeyPair keyPairA = keyGen.generateKeyPair();
keyGen.initialize(ike2048());
KeyPair keyPairB = keyGen.generateKeyPair();
KeyAgreement kaA = KeyAgreement.getInstance("DH");
kaA.init(keyPairA.getPrivate());
try {
kaA.doPhase(keyPairB.getPublic(), true);
byte[] kAB = kaA.generateSecret();
fail("Generated secrets with mixed keys " + TestUtil.bytesToHex(kAB) + ", ");
} catch (java.security.GeneralSecurityException ex) {
// This is expected.
}
}
private SecretKey t13DeriveKey(String algorithm,
AlgorithmParameterSpec params) throws IOException {
try {
KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
ka.init(localPrivateKey);
ka.doPhase(peerPublicKey, true);
SecretKey sharedSecret =
ka.generateSecret("TlsPremasterSecret");
HashAlg hashAlg = context.negotiatedCipherSuite.hashAlg;
SSLKeyDerivation kd = context.handshakeKeyDerivation;
HKDF hkdf = new HKDF(hashAlg.name);
if (kd == null) { // No PSK is in use.
// If PSK is not in use Early Secret will still be
// HKDF-Extract(0, 0).
byte[] zeros = new byte[hashAlg.hashLength];
SecretKeySpec ikm =
new SecretKeySpec(zeros, "TlsPreSharedSecret");
SecretKey earlySecret =
hkdf.extract(zeros, ikm, "TlsEarlySecret");
kd = new SSLSecretDerivation(context, earlySecret);
}
// derive salt secret
SecretKey saltSecret = kd.deriveKey("TlsSaltSecret", null);
// derive handshake secret
return hkdf.extract(saltSecret, sharedSecret, algorithm);
} catch (GeneralSecurityException gse) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(gse);
}
}
private static byte[] dhComputeSecret(PrivateKey ourPrivateKey, PublicKey theirPublicKey)
throws NoSuchAlgorithmException, InvalidKeyException {
KeyAgreement agreement = KeyAgreement.getInstance(KA_ALG);
try {
agreement.init(ourPrivateKey);
} catch (RuntimeException ex) {
// Rethrow the RuntimeException as InvalidKeyException
throw new InvalidKeyException(ex);
}
agreement.doPhase(theirPublicKey, /*lastPhase=*/ true);
return agreement.generateSecret();
}
SecretKey getAgreedSecret(
PublicKey peerPublicKey) throws SSLHandshakeException {
try {
KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
ka.init(privateKey);
ka.doPhase(peerPublicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(e);
}
}
/**
* 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.
* @param keyIsValidated whether the {@code peerPublicKey} has beed
* validated
* @return the secret, which is an unsigned big-endian integer
* the same size as the Diffie-Hellman modulus.
*/
SecretKey getAgreedSecret(BigInteger peerPublicValue,
boolean keyIsValidated) throws SSLHandshakeException {
try {
KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
DHPublicKeySpec spec =
new DHPublicKeySpec(peerPublicValue, modulus, base);
PublicKey publicKey = kf.generatePublic(spec);
KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
// validate the Diffie-Hellman public key
if (!keyIsValidated &&
!KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
try {
KeyUtil.validate(spec);
} catch (InvalidKeyException ike) {
// prefer handshake_failure alert to internal_error alert
throw new SSLHandshakeException(ike.getMessage());
}
}
ka.init(privateKey);
ka.doPhase(publicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(e);
}
}
/**
* 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.
* @param keyIsValidated whether the {@code peerPublicKey} has beed
* validated
* @return the secret, which is an unsigned big-endian integer
* the same size as the Diffie-Hellman modulus.
*/
SecretKey getAgreedSecret(BigInteger peerPublicValue,
boolean keyIsValidated) throws IOException {
try {
KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
DHPublicKeySpec spec =
new DHPublicKeySpec(peerPublicValue, modulus, base);
PublicKey publicKey = kf.generatePublic(spec);
KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
// validate the Diffie-Hellman public key
if (!keyIsValidated &&
!KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
try {
KeyUtil.validate(spec);
} catch (InvalidKeyException ike) {
// prefer handshake_failure alert to internal_error alert
throw new SSLHandshakeException(ike.getMessage());
}
}
ka.init(privateKey);
ka.doPhase(publicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw new RuntimeException("Could not generate secret", e);
}
}
SecretKey getAgreedSecret(
PublicKey peerPublicKey) throws SSLHandshakeException {
try {
KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
ka.init(privateKey);
ka.doPhase(peerPublicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(e);
}
}
/**
* 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.
* @param keyIsValidated whether the {@code peerPublicKey} has beed
* validated
* @return the secret, which is an unsigned big-endian integer
* the same size as the Diffie-Hellman modulus.
*/
SecretKey getAgreedSecret(BigInteger peerPublicValue,
boolean keyIsValidated) throws SSLHandshakeException {
try {
KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
DHPublicKeySpec spec =
new DHPublicKeySpec(peerPublicValue, modulus, base);
PublicKey publicKey = kf.generatePublic(spec);
KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
// validate the Diffie-Hellman public key
if (!keyIsValidated &&
!KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
try {
KeyUtil.validate(spec);
} catch (InvalidKeyException ike) {
// prefer handshake_failure alert to internal_error alert
throw new SSLHandshakeException(ike.getMessage());
}
}
ka.init(privateKey);
ka.doPhase(publicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(e);
}
}
SecretKey getAgreedSecret(
PublicKey peerPublicKey) throws SSLHandshakeException {
try {
KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
ka.init(privateKey);
ka.doPhase(peerPublicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(e);
}
}
SecretKey getAgreedSecret(
PublicKey peerPublicKey) throws SSLHandshakeException {
try {
KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
ka.init(privateKey);
ka.doPhase(peerPublicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(e);
}
}
/**
* 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.
* @param keyIsValidated whether the {@code peerPublicKey} has beed
* validated
* @return the secret, which is an unsigned big-endian integer
* the same size as the Diffie-Hellman modulus.
*/
SecretKey getAgreedSecret(BigInteger peerPublicValue,
boolean keyIsValidated) throws SSLHandshakeException {
try {
KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
DHPublicKeySpec spec =
new DHPublicKeySpec(peerPublicValue, modulus, base);
PublicKey publicKey = kf.generatePublic(spec);
KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
// validate the Diffie-Hellman public key
if (!keyIsValidated &&
!KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
try {
KeyUtil.validate(spec);
} catch (InvalidKeyException ike) {
// prefer handshake_failure alert to internal_error alert
throw new SSLHandshakeException(ike.getMessage());
}
}
ka.init(privateKey);
ka.doPhase(publicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(e);
}
}
public static byte[] getS(PrivateKey privateKey, byte[] publicKey) {
try {
KeyAgreement agreement = KeyAgreement.getInstance("ECDH");
agreement.init(privateKey);
agreement.doPhase(decodePublicKey(publicKey), true);
return agreement.generateSecret();
} catch (NoSuchAlgorithmException | InvalidKeyException | IllegalStateException
| WebAuthnException e) {
throw new RuntimeException(e);
}
}
/**
* 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.
* @param keyIsValidated whether the {@code peerPublicKey} has beed
* validated
* @return the secret, which is an unsigned big-endian integer
* the same size as the Diffie-Hellman modulus.
*/
SecretKey getAgreedSecret(BigInteger peerPublicValue,
boolean keyIsValidated) throws SSLHandshakeException {
try {
KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
DHPublicKeySpec spec =
new DHPublicKeySpec(peerPublicValue, modulus, base);
PublicKey publicKey = kf.generatePublic(spec);
KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
// validate the Diffie-Hellman public key
if (!keyIsValidated &&
!KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
try {
KeyUtil.validate(spec);
} catch (InvalidKeyException ike) {
// prefer handshake_failure alert to internal_error alert
throw new SSLHandshakeException(ike.getMessage());
}
}
ka.init(privateKey);
ka.doPhase(publicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw (SSLHandshakeException) new SSLHandshakeException(
"Could not generate secret").initCause(e);
}
}
@Override
public void main(Provider prov) throws Exception {
if (prov.getService("KeyAgreement", "DH") == null) {
System.out.println("DH not supported, skipping");
return;
}
try {
System.out.println("testing generateSecret()");
DHPublicKeySpec publicSpec;
DHPrivateKeySpec privateSpec;
KeyFactory kf = KeyFactory.getInstance("DH");
KeyAgreement ka = KeyAgreement.getInstance("DH", prov);
KeyAgreement kbSunJCE = KeyAgreement.getInstance("DH", "SunJCE");
DHPrivateKeySpec privSpecA = new DHPrivateKeySpec(xa, p, g);
DHPublicKeySpec pubSpecA = new DHPublicKeySpec(ya, p, g);
PrivateKey privA = kf.generatePrivate(privSpecA);
PublicKey pubA = kf.generatePublic(pubSpecA);
DHPrivateKeySpec privSpecB = new DHPrivateKeySpec(xb, p, g);
DHPublicKeySpec pubSpecB = new DHPublicKeySpec(yb, p, g);
PrivateKey privB = kf.generatePrivate(privSpecB);
PublicKey pubB = kf.generatePublic(pubSpecB);
ka.init(privA);
ka.doPhase(pubB, true);
byte[] n1 = ka.generateSecret();
kbSunJCE.init(privB);
kbSunJCE.doPhase(pubA, true);
byte[] n2 = kbSunJCE.generateSecret();
if (Arrays.equals(n1, n2) == false) {
throw new Exception("values mismatch!");
} else {
System.out.println("values: same");
}
System.out.println("testing generateSecret(byte[], int)");
byte[] n3 = new byte[n1.length];
ka.init(privB);
ka.doPhase(pubA, true);
int n3Len = ka.generateSecret(n3, 0);
if (n3Len != n3.length) {
throw new Exception("PKCS11 Length mismatch!");
} else System.out.println("PKCS11 Length: ok");
byte[] n4 = new byte[n2.length];
kbSunJCE.init(privA);
kbSunJCE.doPhase(pubB, true);
int n4Len = kbSunJCE.generateSecret(n4, 0);
if (n4Len != n4.length) {
throw new Exception("SunJCE Length mismatch!");
} else System.out.println("SunJCE Length: ok");
if (Arrays.equals(n3, n4) == false) {
throw new Exception("values mismatch! ");
} else {
System.out.println("values: same");
}
} catch (Exception ex) {
System.out.println("Unexpected ex: " + ex);
ex.printStackTrace();
throw ex;
}
}
@Override
public void main(Provider provider) throws Exception {
if (provider.getService("KeyAgreement", "DH") == null) {
System.out.println("DH not supported, skipping");
return;
}
try {
DHPublicKeySpec publicSpec;
DHPrivateKeySpec privateSpec;
KeyFactory kf = KeyFactory.getInstance("DH", provider);
KeyAgreement ka = KeyAgreement.getInstance("DH", provider);
PrivateKey pr1 = kf.generatePrivate(new DHPrivateKeySpec(x1, p, g));
PublicKey pu2 = kf.generatePublic(new DHPublicKeySpec(y2, p, g));
PublicKey pu3 = kf.generatePublic(new DHPublicKeySpec(y3, p, g));
ka.init(pr1);
ka.doPhase(pu2, true);
byte[] n2 = ka.generateSecret();
if (Arrays.equals(s2, n2) == false) {
throw new Exception("mismatch 2");
}
System.out.println("short ok");
ka.init(pr1);
ka.doPhase(pu3, true);
byte[] n3 = ka.generateSecret();
if (Arrays.equals(s3, n3) == false) {
throw new Exception("mismatch 3");
}
System.out.println("normal ok");
} catch (Exception ex) {
System.out.println("Unexpected Exception: " + ex);
ex.printStackTrace();
throw ex;
}
/*
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", provider);
kpg.initialize(512);
// KeyPair kp1 = kpg.generateKeyPair();
// System.out.println(kp1.getPublic());
// System.out.println(kp1.getPrivate());
while (true) {
KeyAgreement ka = KeyAgreement.getInstance("DH", provider);
ka.init(pr1);
KeyPair kp2 = kpg.generateKeyPair();
ka.doPhase(kp2.getPublic(), true);
byte[] sec = ka.generateSecret();
if (sec.length == 64) {
System.out.println(kp2.getPrivate());
System.out.println(kp2.getPublic());
System.out.println(toString(sec));
break;
}
}
/**/
}