下面列出了javax.crypto.KeyAgreement#generateSecret ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/** Check that key agreement using DH works. */
@SuppressWarnings("InsecureCryptoUsage")
@Test
public void testDh() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");
DHParameterSpec dhparams = ike2048();
keyGen.initialize(dhparams);
KeyPair keyPairA = keyGen.generateKeyPair();
KeyPair keyPairB = keyGen.generateKeyPair();
KeyAgreement kaA = KeyAgreement.getInstance("DH");
KeyAgreement kaB = KeyAgreement.getInstance("DH");
kaA.init(keyPairA.getPrivate());
kaB.init(keyPairB.getPrivate());
kaA.doPhase(keyPairB.getPublic(), true);
kaB.doPhase(keyPairA.getPublic(), true);
byte[] kAB = kaA.generateSecret();
byte[] kBA = kaB.generateSecret();
assertEquals(TestUtil.bytesToHex(kAB), TestUtil.bytesToHex(kBA));
}
/**
* 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);
}
}
/** Checks that key agreement using ECDH works. */
@Test
public void testBasic() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1");
keyGen.initialize(ecSpec);
KeyPair keyPairA = keyGen.generateKeyPair();
KeyPair keyPairB = keyGen.generateKeyPair();
KeyAgreement kaA = KeyAgreement.getInstance("ECDH");
KeyAgreement kaB = KeyAgreement.getInstance("ECDH");
kaA.init(keyPairA.getPrivate());
kaB.init(keyPairB.getPrivate());
kaA.doPhase(keyPairB.getPublic(), true);
kaB.doPhase(keyPairA.getPublic(), true);
byte[] kAB = kaA.generateSecret();
byte[] kBA = kaB.generateSecret();
assertEquals(TestUtil.bytesToHex(kAB), TestUtil.bytesToHex(kBA));
}
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 byte[] generateEcdhSecret(PrivateKey privateKey, PublicKey publicKey, ProviderContext providerContext) throws JoseException
{
String keyAgreementProvider = providerContext.getSuppliedKeyProviderContext().getKeyAgreementProvider();
KeyAgreement keyAgreement = getKeyAgreement(keyAgreementProvider);
try
{
keyAgreement.init(privateKey);
keyAgreement.doPhase(publicKey, true);
}
catch (java.security.InvalidKeyException e)
{
throw new InvalidKeyException("Invalid Key for " + getJavaAlgorithm() + " key agreement." ,e);
}
return keyAgreement.generateSecret();
}
SecretKey getAgreedSecret(PublicKey peerPublicKey) {
try {
KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
ka.init(privateKey);
ka.doPhase(peerPublicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw new RuntimeException("Could not generate secret", e);
}
}
private SecretKey t13DeriveKey(String algorithm,
AlgorithmParameterSpec params) throws IOException {
try {
KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
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);
}
}
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);
}
}
/**
* Handle the TLSv1.3 objects, which use the HKDF algorithms.
*/
private SecretKey t13DeriveKey(String algorithm,
AlgorithmParameterSpec params) throws IOException {
try {
KeyAgreement ka = KeyAgreement.getInstance(algorithmName);
ka.init(localPrivateKey);
ka.doPhase(peerPublicKey, true);
SecretKey sharedSecret
= ka.generateSecret("TlsPremasterSecret");
CipherSuite.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);
}
}
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) {
try {
KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
ka.init(privateKey);
ka.doPhase(peerPublicKey, true);
return ka.generateSecret("TlsPremasterSecret");
} catch (GeneralSecurityException e) {
throw new RuntimeException("Could not generate secret", 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);
}
}
static public byte[] decryptBytes(byte[] data, String dhSKAlgo, PublicKey publicKey)
throws Exception{
try {
KeyAgreement ka = KeyAgreement.getInstance("DH");
ka.init(dhPrivateKey);
ka.doPhase(publicKey, true);
Cipher decrypt;
int keysize = getKeySize(dhSKAlgo);
int blocksize = getBlockSize(dhSKAlgo);
if (keysize == -1 || blocksize == -1) {
SecretKey sKey = ka.generateSecret(dhSKAlgo);
decrypt = Cipher.getInstance(dhSKAlgo);
decrypt.init(Cipher.DECRYPT_MODE, sKey);
}
else {
String algoStr = getDhAlgoStr(dhSKAlgo);
byte[] sKeyBytes = ka.generateSecret();
SecretKeySpec sks = new SecretKeySpec(sKeyBytes, 0, keysize, algoStr);
IvParameterSpec ivps = new IvParameterSpec(sKeyBytes, keysize, blocksize);
decrypt = Cipher.getInstance(algoStr + "/CBC/PKCS5Padding");
decrypt.init(Cipher.DECRYPT_MODE, sks, ivps);
}
byte[] decrptBytes = decrypt.doFinal(data);
return decrptBytes;
}catch(Exception ex) {
throw ex;
}
}
/**
* 构建密钥
*
* @param publicKey
* 公钥
* @param privateKey
* 私钥
*
* @return byte[] 本地密钥
*
* @throws Exception
*/
public static byte[] getSecretKey(byte[] publicKey, byte[] privateKey) throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException {
// 实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 初始化公钥
// 密钥材料转换
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey);
// 产生公钥
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
// 初始化私钥
// 密钥材料转换
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
// 产生私钥
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 实例化
KeyAgreement keyAgree = KeyAgreement.getInstance(keyFactory.getAlgorithm());
// 初始化
keyAgree.init(priKey);
keyAgree.doPhase(pubKey, true);
// 生成本地密钥
SecretKey secretKey = keyAgree.generateSecret(SECRET_KEY_ALGORITHM);
return secretKey.getEncoded();
}
/**
* 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 p) throws Exception {
if (p.getService("KeyAgreement", "ECDH") == null) {
System.out.println("Not supported by provider, skipping");
return;
}
if (isBadNSSVersion(p)) {
return;
}
if (isBadSolarisSparc(p)) {
return;
}
// Check if this is sparc for later failure avoidance.
boolean sparc = false;
if (props.getProperty("os.arch").equals("sparcv9")) {
sparc = true;
System.out.println("This is a sparcv9");
}
Random random = new Random();
byte[] data = new byte[2048];
random.nextBytes(data);
List<ECParameterSpec> curves = getKnownCurves(p);
for (ECParameterSpec params : curves) {
System.out.println("Testing " + params + "...");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", p);
kpg.initialize(params);
KeyPair kp1, kp2;
kp1 = kpg.generateKeyPair();
kp2 = kpg.generateKeyPair();
testSigning(p, "SHA1withECDSA", data, kp1, kp2);
// Check because Solaris ncp driver does not support these but
// Solaris metaslot causes them to be run.
try {
testSigning(p, "SHA224withECDSA", data, kp1, kp2);
testSigning(p, "SHA256withECDSA", data, kp1, kp2);
testSigning(p, "SHA384withECDSA", data, kp1, kp2);
testSigning(p, "SHA512withECDSA", data, kp1, kp2);
} catch (ProviderException e) {
if (sparc) {
Throwable t = e.getCause();
if (t instanceof sun.security.pkcs11.wrapper.PKCS11Exception &&
t.getMessage().equals("CKR_ATTRIBUTE_VALUE_INVALID")) {
System.out.print("-Failure not uncommon. Probably pre-T4.");
} else {
throw e;
}
} else {
throw e;
}
}
System.out.println();
KeyAgreement ka1 = KeyAgreement.getInstance("ECDH", p);
ka1.init(kp1.getPrivate());
ka1.doPhase(kp2.getPublic(), true);
byte[] secret1 = ka1.generateSecret();
KeyAgreement ka2 = KeyAgreement.getInstance("ECDH", p);
ka2.init(kp2.getPrivate());
ka2.doPhase(kp1.getPublic(), true);
byte[] secret2 = ka2.generateSecret();
if (Arrays.equals(secret1, secret2) == false) {
throw new Exception("Secrets do not match");
}
}
System.out.println("OK");
}
@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;
}
}